[c++] int64_t

64ビットの符号付き整数型
64ビット固定の場合はlong longよりも推奨される

int64_t x = 0LL;

[C++] constexpr

constexprを使わないケース
### 変数
– constでない変数
– クラスのメンバ変数
– 標準入力などの非constexpr関数を用いて計算する値
– 引数などのconstexprでない可能性がある値を用いて計算する値
### 関数
– inline化できない関数
– 引数でもthisでもない非constexprな外側の変数を参照する操作を含む関数
– 引数でもthisでもない外側に副作用を及ぼすような操作を含む関数


#include

auto answer() {return 42;}

constexpr auto auto_constexpr() {return 42;}

constexpr auto answer_print(){
return 42;
}

int main(){
const expr auto b = answer_constexpr();

std::cout << /* a << ", " << */ b << /* ", " << c << */ std::endl; return 0; } [code]

C++ mapの使い方

key, valueの連想配列class

struct Person {
    public:
        Person(const string &name, int height)
            : m_name(name)
            , m_height(height)
            {}
    public:
        string m_name;
        int m_height;
}

    ...
    map<Person, int> mp;
    Person p("aaa", 180);
    mp[p] = 123;

c++ cstdint

符号付き、符号なしで型の指定ができる

int8_t、int16_t、int32_t、int64_t、uint8_t、uint16_t、uint32_t、uint64_t、int_fast8_t、int_fast16_t、int_fast32_t、int_fast64_t、uint_fast8_t、uint_fast16_t、uint_fast32_t、uint_fast64_t、int_least8_t、int_least16_t、int_least32_t、int_least64_t、uint_least8_t、uint_least16_t、uint_least32_t、uint_least64_t、intmax_t、uintmax_t、intptr_t、uintptr_t

それにしても多いですね

CMakeの使い方2

good_morning.hpp

#ifndef GOOD_MORNING_H
#define GOOD_MORNING_H

void good_morning();

#endif

good_morning.cpp

#include <iostream>
#include "good_morning.hpp"

void good_morning() {
    std::cout << "Good Monring!" << std::endl;
}

main.cpp

#include "hello.hpp"
#include "good_morning.hpp"

int main(){
    hello();
    good_morning();
}

$ g++ -c hello.cpp good_morning.cpp
$ ar rvs libgreetings.a hello.o good_morning.o
ar: creating libgreetings.a
a – hello.o
a – good_morning.o
$ g++ main.cpp libgreetings.a
$ ./a.out
Hello!
Good Monring!

[C++] ファイルの分割

C++におけるファイルの分割はクラス定義単位で行う

### ヘッダファイル
マクロ定義、型定義、プロトタイプ宣言の3つを書くのが基本
C++ではクラスを利用するには、そのクラスが提供するヘッダファイルを取り込む必要がある
以下のようなファイルがあったとする

class POS {
    private:
        int x;
        int y;
    
    public:
        POS();
        int setPos(int tmpx, int tmpy);
}

POS::POS(){
    x = 0;
    y = 0;
}

int POS::setPos(int tmpx, int tmpy){
    x = tmpx;
    y = tmpy;
    
    return 0;
}

これを分割する場合

POS.h

#ifndef POS_H
#define POS_H

class POS {
    private:
        int x;
        int y;
    
    public:
        POS();
        int setPos(int tmpx, int tmpy);
}

#endif

POS.cpp

#include "POS.h"

POS::POS(){
    x = 0;
    y = 0;
}

int POS::setPos(int tmpx, int tmpy){
    x = tmpx;
    y = tmpy;
    
    return 0;
}

つまり、最初にheader情報を見て、全体の流れを理解してからソースファイルを見ていくのね。※以前はcppを先に見て、.hは付加情報かと思っていました…orz

HeadersSyncState::ProcessingResult HeadersSyncState::ProcessNextHeaders(const
std::vector& received_headers, const bool full_headers_message)
で、ProcessingResult ProcessNextHeaders となっているのは、headerssync.hで、ProcessingResultの構造体を示していたので、このProcessingResultの型で返却して欲しい という書き方なのね。

struct ProcessingResult {
        std::vector<CBlockHeader> pow_validated_headers;
        bool success{false};
        bool request_more{false};
    };

[bitcoin] headerssync-paramsって何?

Readmeを読むと以下のように書いている
A script to generate optimal parameters for the headerssync module (src/headerssync.cpp). It takes no command-line
options, as all its configuration is set at the top of the file. It runs many times faster inside PyPy. Invocation:
つまり、node間でのヘッダー情報のやり取りのことだ。c++ファイルのヘッダではない。stateで、 PRESYNC、REDOWNLOAD、FINALとある。

src/headerssync.h, src/headerssync.cpp を見てみる。
### headerssync.h
A compressed CBlockHeader, which leaves out the prevhash
HeadersSyncState
We wish to download a peer’s headers chain in a DoS-resistant way.
* – In the first download phase, called pre-synchronization, we can calculate
* the work on the chain as we go (just by checking the nBits value on each
* header, and validating the proof-of-work).
In phase 1 (presync)
In phase 2 (redownload)

#### headerssync.cpp
// The two constants below are computed using the simulation script in
// contrib/devtools/headerssync-params.py.
m_max_commitments = 6*(Ticks(NodeClock::now() – NodeSeconds{std::chrono::seconds{chain_start->GetMedianTimePast()}}) + MAX_FUTURE_BLOCK_TIME) / HEADER_COMMITMENT_PERIOD;

downloadはこれでやってる?

    if (m_current_chain_work >= m_minimum_required_work) {
        m_redownloaded_headers.clear();
        m_redownload_buffer_last_height = m_chain_start->nHeight;
        m_redownload_buffer_first_prev_hash = m_chain_start->GetBlockHash();
        m_redownload_buffer_last_hash = m_chain_start->GetBlockHash();
        m_redownload_chain_work = m_chain_start->nChainWork;
        m_download_state = State::REDOWNLOAD;
        LogPrint(BCLog::NET, "Initial headers sync transition with peer=%d: reached sufficient work at height=%i, redownloading from height=%i\n", m_id, m_current_height, m_redownload_buffer_last_height);
    }

downloadのstatusに応じて処理しているのはわかるが、getHashの処理とかはheaderssync.cppの中には書いてないように見えるがどこでやってるんだろうか?

あと、基本的に、HeadersSyncState::${処理}と書かれていますね。
なんか凄いな…

[C++] 循環参照

クラスの相互参照における問題
A.h

#ifndef _A_H_
#define _A_H_

#include "B.h"

class A {
    B* m_bB;
    ...
}

#endif // _A_H_

ifndef, define, endifは重複回避

B.h

#ifndef _B_H_
#define _B_H_

#include "B.h"

class B {
    A* m_bA;
    ...
}

#endif // _B_H_

お互いに参照していると、いつまで経っても参照が終わらなくなってしまう

#ifndef _A_H_
#define _A_H_

class B;

class A {
private:
    B* m_bB;
public:
    A();
    void foo();
    void bar();
    ...
}

#endif // _A_H_
#ifndef _B_H_
#define _B_H_

class A;

class B {
private: 
    A* m_bA;
public:
    B(A* pA);
    void hoge();
}

#endif // _B_H_

includeはしていないのだが、うーん、なんかよくわからんな…

[C++] for文のautoの書き方

std::vector<int> v;

for(std::vector<int>::const_iterator it = v.begin(), e=v.end(); it != e; ++it){
    std::cout << *it << std::endl;
}

c++11の範囲for文を使うと以下のように書ける

std::vector<int> v;

for(const auto& e: v){
    std::cout << e << std::endl;
}

### 範囲for文(range-based for statement)
配列やコンテナなど複数の要素を持つものから、全ての要素に含まれる値を取り出して処理する

#include <iostream>
using namespace std;

int main() {
    int a[] = {1, 2, 3, 4, 5};
    int sum = 0;
    for(int x : a){
        sum += x;
    }
    cout << "sum = " << sum << end;
    return 0;
}

vector要素の出力

    vector<string> v(5);
    for (int i = 0; i < v.size(); i++){
        string& x = v[i];
        cin >> x;
    }

autoは型推論を行うキーワード

    vector<string> v(5);
    for (auto& x : v){
        cin >> x;
    }

[C++] ヘッダとソースでファイルを分ける

C++ではクラスの定義とそのメンバ関数の定義をヘッダファイルとソースファイルで分割するのが一般的である

### ファイルを分割していない例
c.hpp

#ifndef C_HPP
#define C_HPP

class c {
    private:
    int m_value;

    public:
    int get() {
        return m_value;
    }

    void set(int const value){
        m_value = value;
    }
};

#endif

### ファイルを分割した例
c.hpp

#ifndef C_HPP
#define C_HPP

class c {
    private:
    int m_value;

    public:
    int get();

    void set(int const value);
};

#endif

c.cpp

#include "c.hpp"

int c::get(){
    return m_value;
}

void c::set(int const value){
    m_value = value;
}

インラインで書くこともある

#ifndef C_HPP
#define C_HPP

class c {
private:
int m_value;

public:
int get();

void set(int const value);
};

inline int c::get(){
return m_value;
}

inline void c::set(int const value){
m_value = value;
}

#endif

bitcoinのソースコードで、基本hppとcppのファイル構造になっていたが、謎が解けた。