Mengapa kode ini dikompilasi?
_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 menegaskan pertama jelas benar, tetapi saya akan berharap baris terakhir gagal, karena pemahaman saya adalah yang sizeof()
harus mengevaluasi ke literer integer, yang tidak dapat diperlakukan sebagai array. Dengan kata lain, itu akan gagal dengan cara yang sama seperti baris berikut gagal:
_Static_assert(4[0] == 4, "");
Menariknya, yang berikut ini memang gagal dikompilasi (yang seharusnya melakukan hal yang sama, bukan?):
_Static_assert(*sizeof(my_arr) == 4, "");
galat: argumen tipe tidak valid dari '*' unary (memiliki 'int unsigned lama') _Static_assert (* sizeof (my_arr) == 4, "");
Jika itu penting, saya menggunakan gcc 5.3.0
( sizeof( my_arr ) )[ 0 ]
gagal.Jawaban:
sizeof
bukan fungsi. Ini operator seperti unary!
atau~
.sizeof(my_arr)[0]
mem-parsing assizeof (my_arr)[0]
, yang hanyasizeof my_arr[0]
dengan kurung redundan.Ini seperti
!(my_arr)[0]
mem - parsing seperti!(my_arr[0])
.Secara umum, operator postfix memiliki prioritas lebih tinggi daripada operator prefix di C.
sizeof *a[i]++
parses assizeof (*((a[i])++))
(operator postfix[]
dan++
diterapkana
terlebih dahulu, kemudian operator prefix*
dansizeof
).(Ini adalah versi ekspresi
sizeof
. Ada juga versi tipe, yang mengambil nama tipe tanda kurung:.sizeof (TYPE)
Dalam hal ini parens akan diperlukan dan bagian darisizeof
sintaks.)sumber
sizeof
menjadi operator unary."... parses as sizeof (my_arr[0])"
? Menambahkan ruang saja tidak benar-benar mengubah apa pun.sizeof((my_array)[0])
sebagai gantinyasizeof
memiliki dua "versi":sizeof(type name)
dansizeof expression
. Yang pertama membutuhkan sepasang()
argumen. Tapi yang terakhir - yang berekspresi sebagai argumen - tidak ada di()
sekitar argumennya. Apa pun yang()
Anda gunakan dalam argumen dipandang sebagai bagian dari ekspresi argumen, bukan bagian darisizeof
sintaks itu sendiri.Karena
my_arr
diketahui kompiler sebagai nama objek, bukan nama tipe, Andasizeof(my_arr)[0]
sebenarnya dilihat oleh kompiler sebagaimanasizeof
diterapkan pada ekspresi:, disizeof (my_arr)[0]
mana(my_arr)[0]
ekspresi argumen. Nama()
array di sekelilingnya murni berlebihan. Seluruh ekspresi diartikan sebagaisizeof my_arr[0]
. Ini sama dengan sebelumnyasizeof(my_arr[0])
.(Ini berarti, BTW, bahwa sebelumnya Anda
sizeof(my_arr[0])
juga berisi sepasang berlebihan()
.)Ini adalah kesalahpahaman yang agak luas bahwa
sizeof
sintaksis entah bagaimana memerlukan sepasang()
argumen. Kesalahpahaman ini adalah yang menyesatkan intuisi orang ketika menafsirkan ekspresi seperti itusizeof(my_arr)[0]
.sumber
int
bukan ekspresi yang valid, sehingga Anda tidak dapat menggunakan bentuk kedua dengan itu.[]
memiliki prioritas lebih tinggi darisizeof
. Begitusizeof(my_arr)[0]
juga dengansizeof((my_arr)[0])
.Berikut ini tautan ke tabel prioritas.
sumber
Anda menggunakan versi
sizeof
operator yang menggunakan ekspresi sebagai parameter. Berbeda dengan yang mengambil jenis, itu tidak memerlukan tanda kurung. Oleh karena itu, operannya sederhana(my_arr)[0]
, dengan tanda kurung menjadi berlebihan.sumber