@Kostya: Meine Kopie von K & R (die früheste Beschreibung der C-Sprache, die ich habe) ist sehr weit entfernt und ich kann sie jetzt nicht überprüfen, aber ich bin zu 110% sicher, dass sie im sizeofWesentlichen genauso beschreibt wie C99 Standard heute. sizeofist verfügbar, bevor C 1989 von ANSI standardisiert wurde.
pmg
Antworten:
119
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.
+1 und, um das zu verstärken, sizeofein Operator: Die Klammern "gehören" zum Typ, nicht zum Operator.
PMG
@pmg: Danke für die Klarstellung! Ja, wie Sie bereits erwähnt haben, bezeichnet der Standard sizeofeinen Operator.
Ise Wisteria
4
@pmg: Ich glaube nicht, dass klar ist, wozu die Klammern "gehören". Die Syntax der zweiten Form besteht aus drei Token und einem nicht-terminalen : 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?
Keith Thompson
3
Was ich meine ist, dass 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".
PMG
2
@pmg: Sie können es sicherlich so sehen, aber ich finde es irreführend. Die einzige wirkliche Ähnlichkeit mit einer Besetzung besteht darin, dass sie einen Typnamen in Klammern hat, und das ist nur ein Zufall der syntaktischen Bequemlichkeit. Ich stelle es mir lieber 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.)
Keith Thompson
43
Auf diese Weise wird die Sprache angegeben. Typnamen müssen hier in Klammern gesetzt werden.
Angenommen, die Grammatik sieht folgendermaßen aus:
sizeof unary-expressionsizeof type-name
Nun wäre zB der folgende Ausdruck mehrdeutig:
sizeofint * + 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));
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 isttype-name
, muss er in Klammern gesetzt werden.quelle
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 Beispielsizeof(x)
, und obwohl es wie ein Funktionsaufruf aussieht (wennsizeof
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 istprintf ( <SOMETHING> )
. Die Klammern gehören zu,printf
aber nicht zusizeof
. Wennsizeof
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 seinsizeof(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.
quelle
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));
quelle