Poniższe nie można skompilować:
typedef int arr[10];
int main(void) {
return sizeof arr;
}
sizeof.c:3: error: expected expression before ‘arr’
ale jeśli zmienię to na
sizeof(arr);
wszystko w porządku. Czemu?
Poniższe nie można skompilować:
typedef int arr[10];
int main(void) {
return sizeof arr;
}
sizeof.c:3: error: expected expression before ‘arr’
ale jeśli zmienię to na
sizeof(arr);
wszystko w porządku. Czemu?
sizeofzasadniczo opisuje to samo, co C99 Standard dzisiaj. sizeofjest dostępny, zanim C został znormalizowany przez ANSI w 1989 r.
Odpowiedzi:
Zgodnie z 6.5.3 istnieją dwa formularze sizeof:
sizeof unary-expression
sizeof ( type-name )
Ponieważ arrw twoim kodzie jest a type-name, musi być umieszczony w nawiasach.
sizeofjest to operator: nawias „należy” do typu, a nie do operatora.
sizeofoperatora.
sizeof ( type-name ). Ale dla pierwszej postaci, to może napisać, na przykład, sizeof(x)i choć wygląda wywołania funkcji (jeśli sizeofnie były kluczowe), to naprawdę operator stosowane do ekspresji w nawiasy. Czy to miałeś na myśli?
sizeofsyntaktycznie sizeof <SOMETHING>w przeciwieństwie do funkcji, na przykład a, printfktóre jest printf ( <SOMETHING> ). Nawiasy należą do, printfale nie do sizeof. Kiedy sizeofjest stosowany do nazwy typu w nawiasach, lubię myśleć o tym jako o rzucie niczego - „zwracaniu” tylko typu.
sizeof ( type-name )jako o swoim własnym rodzaju ekspresji. (Standard nazywa go operatorem, ale ( type-name )tak naprawdę nie jest operandem w zwykłym sensie).
W ten sposób określa się język, nazwy typów muszą być tutaj umieszczone w nawiasach.
Załóżmy, że gramatyka wyglądała tak:
sizeof unary-expression
sizeof type-name
Teraz np. Następujące wyrażenie byłoby niejednoznaczne:
sizeof int * + 0
Może to być albo sizeof(int *) + 0albosizeof(int) * +0 . Ta niejednoznaczność nie występuje w przypadku wyrażeń jednoargumentowych, ponieważ gwiazdka dołączona do wyrażenia nie jest wyrażeniem (ale w przypadku niektórych nazw typów dołączenie jednego jest ponownie nazwą typu).
Coś musiało zostać tutaj określone, a wymaganie, aby nazwy typów były umieszczane w nawiasach, jest sposobem na rozwiązanie niejednoznaczności.
Myślę, że to dlatego, że masz typedef. Jeśli go usuniesz, powinien się skompilować.
Przykład z wikipedii:
/* the following code fragment illustrates the use of sizeof
* with variables and expressions (no parentheses needed),
* and with type names (parentheses needed)
*/
char c;
printf("%zu,%zu\n", sizeof c, sizeof (int));