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?
sizeofWesentlichen genauso beschreibt wie C99 Standard heute. sizeofist verfügbar, bevor C 1989 von ANSI standardisiert wurde.
Antworten:
Gemäß 6.5.3 gibt es zwei Formen für sizeofFolgendes:
sizeof unary-expression
sizeof ( type-name )
Da arrIhr Code a ist type-name, muss er in Klammern gesetzt werden.
sizeofein Operator: Die Klammern "gehören" zum Typ, nicht zum Operator.
sizeofeinen 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 sizeofwar kein Schlüsselwort), es ist wirklich ein Bediener auf einen geklammerten Ausdruck angewandt. Hast du das gedacht?
sizeofes syntaktisch ist, sizeof <SOMETHING>im Gegensatz zu Funktionen, zum Beispiel zu einem, printfwas ist printf ( <SOMETHING> ). Die Klammern gehören zu, printfaber nicht zu sizeof. Wenn sizeofes 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 *) + 0oder 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));