362 Stimmen

int a[] = {1,2,}; Warum ist ein nachgestelltes Komma in einer Initialisierungsliste zulässig?

Vielleicht bin ich nicht von diesem Planeten, aber es scheint mir, dass das Folgende ein Syntaxfehler sein sollte:

int a[] = {1,2,}; //extra comma in the end

Ist es aber nicht. Ich war überrascht, als dieser Code in Visual Studio kompiliert wurde, aber ich habe gelernt, dem MSVC-Compiler nicht zu trauen, was die C++-Regeln angeht, also habe ich den Standard überprüft, und er es auch nach der Norm zulässig. Wenn Sie mir nicht glauben, können Sie unter 8.5.1 die Grammatikregeln nachlesen.

enter image description here

Warum ist das erlaubt? Dies mag eine dumme, nutzlose Frage sein, aber ich möchte, dass Sie verstehen, warum ich frage. Wenn es sich um einen Unterfall einer allgemeinen Grammatikregel handeln würde, würde ich es verstehen - man hat beschlossen, die allgemeine Grammatik nicht noch schwieriger zu machen, nur um ein überflüssiges Komma am Ende einer Initialisierungsliste zu verbieten. Aber nein, das zusätzliche Komma ist ausdrücklich erlaubt. Zum Beispiel ist es nicht erlaubt, ein überflüssiges Komma am Ende der Argumentliste eines Funktionsaufrufs zu haben (wenn die Funktion ... ), was normal ist .

Noch einmal: Gibt es einen besonderen Grund für dieses überflüssige Komma? ausdrücklich erlaubt?

4voto

Nikos Athanasiou Punkte 26657

Wie viele andere Dinge auch, ist das nachgestellte Komma in einem Array-Initialisierer eines der Dinge, die C++ von C geerbt hat (und die es für immer unterstützen muss). Eine ganz andere Sichtweise als die, die hier steht wird in dem Buch erwähnt "Tiefe C-Geheimnisse" .

Nachfolgend ein Beispiel mit mehreren "Komma-Paradoxien":

char *available_resources[] = {
"color monitor"           ,
"big disk"                ,
"Cray"                      /* whoa! no comma! */
"on-line drawing routines",
"mouse"                   ,
"keyboard"                ,
"power cables"            , /* and what's this extra comma? */
};

lesen wir:

...das nachgestellte Komma nach dem letzten Initialisierungszeichen ist kein Tippfehler, sondern ein Fleck in der Syntax, der aus dem ursprünglichen C übernommen wurde . Seine Anwesenheit oder Abwesenheit ist erlaubt, hat aber keine Bedeutung . In der Begründung von ANSI C wird behauptet, dass dies die automatische Generierung von C erleichtert. Die Behauptung wäre glaubwürdiger, wenn nachgestellte Kommas in jeder mit Komma getrennten Liste erlaubt wären wie z. B. in Enum-Deklarationen oder mehrere Variablendeklaratoren in einer einzigen Deklaration. Sie sind es nicht.

... für mich macht dies mehr Sinn

2voto

Iravanchi Punkte 5069

Abgesehen von der einfachen Codegenerierung und -bearbeitung ist diese Art von Grammatik einfacher und leichter zu implementieren, wenn Sie einen Parser implementieren möchten. C# folgt dieser Regel an mehreren Stellen, dass es eine Liste von Komma-getrennten Elementen gibt, wie Elemente in einer enum Definition.

1voto

Scott Langham Punkte 55597

Das macht die Codeerstellung einfacher, da Sie nur eine Zeile hinzufügen müssen und das Hinzufügen des letzten Eintrags nicht als Sonderfall behandeln müssen. Dies gilt insbesondere bei der Verwendung von Makros zur Codegenerierung. Es gibt Bestrebungen, die Notwendigkeit von Makros aus der Sprache zu eliminieren, aber ein Großteil der Sprache hat sich Hand in Hand mit der Verfügbarkeit von Makros entwickelt. Durch das zusätzliche Komma können Makros wie die folgenden definiert und verwendet werden:

#define LIST_BEGIN int a[] = {
#define LIST_ENTRY(x) x,
#define LIST_END };

Verwendung:

LIST_BEGIN
   LIST_ENTRY(1)
   LIST_ENTRY(2)
LIST_END

Das ist ein sehr vereinfachtes Beispiel, aber oft wird dieses Muster von Makros für die Definition von Dingen wie Dispatch-, Nachrichten-, Ereignis- oder Übersetzungs-Maps und Tabellen verwendet. Wenn ein Komma am Ende nicht erlaubt wäre, bräuchten wir ein Special:

#define LIST_LAST_ENTRY(x) x

und das wäre sehr umständlich in der Anwendung.

0voto

Wenn also zwei Personen ein neues Element in einer Liste auf verschiedenen Zweigen hinzufügen, kann Git die Änderungen ordnungsgemäß zusammenführen, da Git auf Zeilenbasis arbeitet.

-4voto

zhi_jian Punkte 1

Wenn Sie ein Array ohne spezifizierte Länge verwenden, kann VC++6.0 seine Länge automatisch erkennen. Wenn Sie also "int a[]={1,2,};" verwenden, ist die Länge von a 3, aber das letzte Array wurde nicht initialisiert, Sie können "cout<

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X