Ich bin auf die folgende Initialisierung gestoßen, es ist zu sehen, dass VS2012 einen Fehler anzeigt, der sich über zu viele Initialisierer beschwert. In GCC scheint es das erste Element als Wert zurückzugeben.
Warum wird diese besondere Initialisierung in GCC unterstützt?
#include <stdio.h>
int main()
{
int q = {1,2};
char c = {'s','t','\0'}; /* c is 's' */
printf("%d\n",q); /* prints 1*/
}
C11: 6.7.9 Initialisierung (p11):
Der Initialisierer für einen Skalar soll ein einzelner Ausdruck sein, optional in geschweiften Klammern eingeschlossen.
Daher ist dies erlaubt
int q = {1};
Sie können den Initialisierer für skalare Objekte in geschweiften Klammern ({}
). Beachte das Verb soll wird hier verwendet. Die Norm sagt:
5.1.1.3 Diagnose (P1):
Eine konforme Implementierung muss mindestens eine diagnostische Meldung (identifiziert auf implementierungsdefinierte Weise) erzeugen, wenn eine vorverarbeitende Übersetzungseinheit oder Übersetzungseinheit eine Verletzung einer Syntaxregel oder -einschränkung enthält, selbst wenn das Verhalten auch explizit als undefiniert oder implementierungsdefiniert angegeben ist. definiert
Es liegt also am Compiler, wie er damit umgeht
int q = {1,2};
Kompiliert auf GCC 4.8.1 mit Flags -pedantic -Wall -Wextra
und es löste eine Warnung aus
[Warning] excess elements in scalar initializer [enabled by default]
Jetzt ist die Frage: Was ist mit den verbleibenden Initialisierern passiert?
Es ist ein Insekt.
Notiz: C11: 6.5.17 (p3) sagt, dass die Komma-Operator kann nicht in Kontexten erscheinen, in denen ein Komma verwendet wird, um Elemente in einer Liste zu trennen (z. B. Argumente für Funktionen oder Listen von Initialisierern).
Verwechseln Sie die nicht ,
in {1,2}
mit Komma-Operator. Wie Keith Thompson darauf hingewiesen hat, die Ausdruck im Initialisierer zu sein Zuweisungsausdruck und es darf nicht enthalten sein Komma-Operator auf Top-Niveau. Das heißt, es kann in solchen Kontexten innerhalb eines eingeklammerten Ausdrucks oder innerhalb des zweiten Ausdrucks eines Bedingungsoperators verwendet werden. Im Funktionsaufruf
f(a, (t=3, t+2), c)
Die Funktion hat drei Argumente, von denen das zweite den Wert hat 5
.
Ich frage mich, was es mit den verbleibenden Initialisierern macht: (
– Martin Jakob
9. Februar 2015 um 14:58 Uhr
Wenn Sie Warnungen aktivieren
gcc
wird echt sauer darüber sein.– Iharob Al Asimi
9. Februar 2015 um 15:01 Uhr
GCC 4.8.3 gibt hier eine Warnung aus standardmäßig (also ohne
-Wall
oder irgendwas).– Tim Čas
9. Februar 2015 um 15:02 Uhr
Viele Warnungen… coliru.stacked-crooked.com/a/6691f8768208b710
– Deduplizierer
9. Februar 2015 um 15:03 Uhr
Mein erster Gedanke war, dass es sich um einen Kommaoperator handelt, der das verwirft
1
und nachgeben2
.1,2
ist ein gültiger Ausdruck. Aber die Grammatik erfordert eine Zuweisungsausdruck In diesem Zusammenhang ist ein Komma-Operator auf oberster Ebene nicht zulässig.– Keith Thompson
9. Februar 2015 um 17:15 Uhr