Tech Notes

C++におけるコンマ区切りの変数宣言と初期化順序

C++でこういうコードを書いたとする。

int a = 10, b = a * 2;

初期化がa→bの順で行われるなら問題は起きないが、仮に逆の順だと問題が起きるように思われる。その辺は規格上どうなっているのか調べてみた。

結論から言うと、「コンマ区切りで初期化した場合は左から順に1つずつ宣言したのと同じである」ということが規格上明言されている。冒頭に挙げたような形のコードを心配する必要はない。

T D1, D2, ... Dn;

is usually equivalent to

T D1; T D2; ... T Dn;

C++11: https://timsong-cpp.github.io/cppwp/n3337/dcl.decl#footnote-97

この文言はC++23のワーキングドラフトでも維持されていることを確認している。今後も変わるような理由はないだろう。

「usually」という一言が少し引っかかるが、これは非常に特殊な例の話であり、そう気にするべき話ではないようだ。

1つずつ宣言したのと違う結果になってしまう例外として以下の例が上げられている。

  • 例外1
struct S { /* ... */ };
S S, T; // OK、構造体S型の変数が2つ生成される
struct S { /* ... */ };
S S;
S T;  // コンパイルエラー、この行ではすでにSは構造体の名前でなく変数の名前としての認識が優先
  • 例外2
auto i = 1, j = 2.0;  // コンパイルエラー、2つは同じ型でなければならない
auto i = 1;
auto j = 2.0;  // OK、iはint型でjはdouble型

初期化順序に関する話ではないのでこの記事の本題と関わるものではないだろう。

しかし構造体の名前と同じ名前の変数の宣言が合法なのはだいぶ気持ち悪いな...