Folgendes kann nicht kompiliert werden:
typedef int arr[10];
int main(void) {
return sizeof arr;
}
sizeof.c:3: error: expected expression before ‘arr’
aber wenn ich es ändere
sizeof(arr);
alles ist gut. Warum?
Folgendes kann nicht kompiliert werden:
typedef int arr[10];
int main(void) {
return sizeof arr;
}
sizeof.c:3: error: expected expression before ‘arr’
aber wenn ich es ändere
sizeof(arr);
alles ist gut. Warum?
sizeof
Wesentlichen genauso beschreibt wie C99 Standard heute. sizeof
ist verfügbar, bevor C 1989 von ANSI standardisiert wurde.
Antworten:
Gemäß 6.5.3 gibt es zwei Formen für sizeof
Folgendes:
sizeof unary-expression
sizeof ( type-name )
Da arr
Ihr Code a ist type-name
, muss er in Klammern gesetzt werden.
sizeof
ein Operator: Die Klammern "gehören" zum Typ, nicht zum Operator.
sizeof
einen Operator.
sizeof ( type-name )
. Aber für die erste Form, Sie können schreiben, zum Beispiel sizeof(x)
, und obwohl es wie ein Funktionsaufruf aussieht (wenn sizeof
war kein Schlüsselwort), es ist wirklich ein Bediener auf einen geklammerten Ausdruck angewandt. Hast du das gedacht?
sizeof
es syntaktisch ist, sizeof <SOMETHING>
im Gegensatz zu Funktionen, zum Beispiel zu einem, printf
was ist printf ( <SOMETHING> )
. Die Klammern gehören zu, printf
aber nicht zu sizeof
. Wenn sizeof
es auf einen Typnamen in Klammern angewendet wird, stelle ich mir das gerne als eine Besetzung von nichts vor - "nur" den Typ "zurückgeben".
sizeof ( type-name )
als einen eigenen Ausdruck vor. (Der Standard nennt es einen Operator, ist aber ( type-name )
nicht wirklich ein Operand im üblichen Sinne.)
Auf diese Weise wird die Sprache angegeben. Typnamen müssen hier in Klammern gesetzt werden.
Angenommen, die Grammatik sieht folgendermaßen aus:
sizeof unary-expression
sizeof type-name
Nun wäre zB der folgende Ausdruck mehrdeutig:
sizeof int * + 0
Es könnte entweder sizeof(int *) + 0
oder sein sizeof(int) * +0
. Diese Mehrdeutigkeit tritt bei unären Ausdrücken nicht auf, da ein an einen Ausdruck angehängtes Sternchen kein Ausdruck ist (bei einigen Typnamen ist das Anhängen eines wieder ein Typname).
Hier musste etwas angegeben werden, und die Notwendigkeit, Typnamen in Klammern zu setzen, ist eine Möglichkeit, die Mehrdeutigkeit zu lösen.
Ich denke, das liegt daran, dass du es hast typedef
. Wenn Sie es entfernen, sollte es kompiliert werden.
Beispiel aus Wikipedia:
/* 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));