Ganzzahl q = {1,2}; eigenartige Initialisierungsliste

Lesezeit: 3 Minuten

Benutzer-Avatar
Rohmetall

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*/
}

  • 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 nachgeben 2. 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

Benutzer-Avatar
hackt

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.

  • werden die verbleibenden Initialisierer also ignoriert?

    – Rohmetall

    9. Februar 2015 um 15:06 Uhr

  • Erinnern Sie sich an die folgende Frage, stackoverflow.com/questions/28394871/… , Das Ergebnis ist im Wesentlichen darauf zurückzuführen?

    – Rohmetall

    9. Februar 2015 um 15:09 Uhr

  • Soll” ist das operative Verb in der Spezifikation. Für eine lange Zeit, GCC war Avantgarde in seiner Initialisierungsunterstützung.

    – Bischof

    9. Februar 2015 um 15:12 Uhr

  • @Hacks: Ja. N1570 6.7.9p1: die Syntax von an Initialisierer ist einer von Zuweisungsausdruck, { Initialisierungsliste }oder { Initialisierungsliste , }. (Beachten Sie, dass ein Zuweisungsausdruck muss keinen Zuweisungsoperator haben; Jeder Ausdruck, dessen Top-Level-Operator kein Komma-Operator ist, ist ein Zuweisungsausdruck.)

    – Keith Thompson

    9. Februar 2015 um 18:41 Uhr


  • Ein Zuweisungsausdruck kann einen Kommaoperator enthalten, nur nicht auf der obersten Ebene. int q = { (1, 2) }; wäre legal (aber dumm).

    – Keith Thompson

    9. Februar 2015 um 19:22 Uhr

1370870cookie-checkGanzzahl q = {1,2}; eigenartige Initialisierungsliste

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy