読者です 読者をやめる 読者になる 読者になる

ゆとりーなの日記

日記的な事を書いて行くと思はれる

謎い

std::arrayは要素数指定するのが面倒だなとか思ってノリでこんなコード書いたらコンパイル通りました。

#include <iostream>

struct array {
  int a[];
};

int main() {
  array a = {
    {0, 1, 2}
  };
  std::cout << a.a[1] << "\n" << sizeof(a) << std::endl;
  return 0;
}

出力

1
1

サイズが1とはどういうことなんでしょう。因みに警告出てました。まぁなんか文面的にこの使い方は危ないよというよりかは暗黙メソッド作ってあげれませんよ感が漂ってますね。

warning C4200: 非標準の拡張機能が使用されています : 構造体または共用体中にサイズが 0 の配列があります。 UDT にサイズが 0 の配列が含まれているときに、copy-ctor または copy-assignment オペレーターを生成することはできません。

a[]の部分はどうやら0要素の配列と認識されているらしいです。そうなるとaのサイズが1なのも頷けます。デバッガで見ると、aはint[3]と表示されててちゃんと3要素の配列とみなされている様にも見えます。ということは実行時によきにはからってくれる様なコードが吐かれたってことなんでしょうかね。C99の変数をサイズに指定できる配列みたいな感じなんでしょうか。
因みに配列を初期化しないで要素にアクセスしようとすると、

warning C4739: 変数 'a' への参照はそのストレージ領域を超えています

とこれまた警告をだしてくれます。普通にサイズ指定しないで初期化しない配列を宣言した時点でコンパイルエラーになるのに対してずいぶん甘めです。
まぁ実用面を考えると、MSVCの非標準の拡張機能を使ってるみたいなのと要素数を取得するメソッドの実装が無理ゲー臭が漂っているので使いものにならないでしょうね。