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?
sizeof
zasadniczo opisuje to samo, co C99 Standard dzisiaj. sizeof
jest 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ż arr
w twoim kodzie jest a type-name
, musi być umieszczony w nawiasach.
sizeof
jest to operator: nawias „należy” do typu, a nie do operatora.
sizeof
operatora.
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 sizeof
nie były kluczowe), to naprawdę operator stosowane do ekspresji w nawiasy. Czy to miałeś na myśli?
sizeof
syntaktycznie sizeof <SOMETHING>
w przeciwieństwie do funkcji, na przykład a, printf
które jest printf ( <SOMETHING> )
. Nawiasy należą do, printf
ale nie do sizeof
. Kiedy sizeof
jest 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 *) + 0
albosizeof(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));