sizeof(my_arr)[0] がコンパイルされて sizeof(my_arr[0]) と等しくなるのはなぜですか? 質問する

sizeof(my_arr)[0] がコンパイルされて sizeof(my_arr[0]) と等しくなるのはなぜですか? 質問する

このコードはなぜコンパイルされるのでしょうか?

_Static uint32_t my_arr[2];
_Static_assert(sizeof(my_arr) == 8, "");
_Static_assert(sizeof(my_arr[0]) == 4, "");
_Static_assert(sizeof(my_arr)[0] == 4, "");

最初の 2 つのアサートは明らかに正しいのですが、最後の行は失敗すると予想していました。これは、sizeof()配列として扱うことができない整数リテラルに評価されるはずだと理解しているからです。言い換えると、次の行が失敗するのと同じように失敗します。

_Static_assert(4[0] == 4, "");

興味深いことに、次のコードは実際にコンパイルに失敗します (同じことが起こるはずですよね?):

_Static_assert(*sizeof(my_arr) == 4, "");

エラー: 単項 '*' の無効な型引数 ('long unsigned int' があります) _Static_assert(*sizeof(my_arr) == 4, "");

関係ないかもしれませんが、私はgcc 5.3.0を使用しています

ベストアンサー1

sizeofは関数ではありません。!or のような単項演算子です~

sizeof(my_arr)[0]は として解析されますがsizeof (my_arr)[0]、これはsizeof my_arr[0]冗長な括弧があるだけです。

!(my_arr)[0]これはとして解析するのと同じです!(my_arr[0])

一般に、C では接尾辞演算子の方が接頭辞演算子よりも優先順位が高くなります。sizeof *a[i]++は として解析されますsizeof (*((a[i])++))(接尾辞演算子[]と が最初++に適用されa、次に接頭辞演算子*と が適用されますsizeof)。

(これは の式バージョンですsizeof。また、括弧で囲まれた型名を取る型バージョンもあります: sizeof (TYPE)。その場合、括弧は必須となり、sizeof構文の一部となります。)

おすすめ記事