Was ist diese C ++ - Syntax, die einen von Klammern umgebenen Block dort platziert, wo ein Ausdruck erwartet wird?


78

Ich bin auf dieses seltsame C ++ - Programm gestoßen.

#include <iostream>
using namespace std;
int main()
{
  int a = ({int x; cin >> x; x;});
  cout << a;
}

Kann jemand erklären, was los ist? Wie heißt dieses Konstrukt?


51
es heißt "verschleiere den Code"
BЈовић

2
@VJo: Ich meine, wie heißt dieses "({})" - Konstrukt? Ist es ähnlich wie anonyme Funktionen?
Koshimitsu

1
+1 Blimey, das hatte ich noch nie gesehen. Schade, dass es GNU C / C ++ spezifisch ist ...
sehe

1
+1, sieht wenig ähnlich aus wie Lambda-Funktion :)
Iammilind

18
Ist es nur ich oder gibt es in gcc mehr bizarre Nicht-Standard-Erweiterungen als in jedem anderen Compiler?
David Heffernan

Antworten:


68

Es weist dem Benutzer einen Eingabewert zu aund druckt ihn aus. Dies geschieht mit a Statement Expression.

Anweisungsausdrücke sind gnu gcc Compiler-Erweiterungen werden von den C / C ++ - Standards nicht unterstützt. Daher ist jeder Code, der einen Anweisungsausdruck verwendet, nicht standardkonform und nicht portierbar.

IBM IBM XL C / C ++ v7.0 unterstützt auch Anweisungsausdrücke und die Dokumentation erklärt sie treffend:

Anweisungsausdrücke:

Eine zusammengesetzte Anweisung ist eine Folge von Anweisungen, die in geschweifte Klammern eingeschlossen sind. In GNU C kann eine zusammengesetzte Anweisung in Klammern als Ausdruck in a erscheinen Statement expression.

         .--------------.
         V              |
>>-(--{----statement--;-+--}--)--------------------------------><

Der Wert eines Anweisungsausdrucks ist der Wert des letzten einfachen Ausdrucks, der im gesamten Konstrukt angezeigt wird. Wenn die letzte Anweisung kein Ausdruck ist, ist das Konstrukt vom Typ void und hat keinen Wert.

Immer Kompilieren des Codes durch einen sandard in GCC Auswahl, verwenden Sie eine der Optionen -ansi, -std=c90oder -std=iso9899:1990, -std=c++03, -std=c++0x; Um alle vom Standard geforderten Diagnosen zu erhalten, sollten Sie auch angeben -pedantic(oder -pedantic-errorsob Sie möchten, dass es sich eher um Fehler als um Warnungen handelt).


56

Es ist eine GCC-Erweiterung. Kompilieren Sie Ihren Code mit dem -pedanticFlag, wenn Sie solche Dinge loswerden möchten (und das möchten Sie wirklich ).


10
Ich vermute, es hat so viele Stimmen bekommen, weil viele Menschen erleichtert waren, nachdem sie erfahren hatten, dass etwas, von dem sie noch nichts gehört oder das sie nicht benutzt hatten, sowieso nicht Standard ist.
Blagovest Buyukliev

18

Es erstellt einen Inline-Bereich, deklariert xdarin, liest ihn aus der Standardeingabe und die gesamte Anweisung wird schließlich ausgewertet x, der zugewiesen ist a.

Der Komma-Operator funktioniert ähnlich, benötigt jedoch keinen separaten Bereich. Zum Beispiel:

int x;
int a = (cin >> x, x);

würde das gleiche tun. Alle mit Kommas verbundenen Anweisungen werden nacheinander ausgeführt, und das Ergebnis des gesamten Ausdrucks wird auf den Wert des Operanden ganz rechts gesetzt.


Gibt es einen bestimmten Namen für "({})"?
Koshimitsu

@Koshimitsu: Das gibt es nicht, da es sich um eine Kombination von Operatoren handelt (wenn Sie sie so nennen möchten). Die geschweiften Klammern {} definieren in diesem Fall den Anfang ({) und das Ende (}) eines Bereichs. Die regulären Klammern dienen nur dazu, die Definition und den Rückgabewert des Bereichs zu kapseln. Ich bin mir nicht ganz sicher, ob diese regulären Klammern in diesem Fall weggelassen werden können, aber ich würde erwarten, dass dies möglich ist.
Rycul

1
@Koshimitsu: Ich bin nicht sehr vertraut mit C ++, aber in C ist es vollkommen legal und ich habe es oft benutzt.
Blagovest Buyukliev

1
@Neil: Nun, vielleicht liegt es daran, dass gcc der einzige C-Compiler ist, den ich benutze, daher bin ich irregeführt worden.
Blagovest Buyukliev

13

Ich glaube nicht, dass dies Standard C ++ ist. Es ist wahrscheinlich eine compilerspezifische Erweiterung, die es einem inneren Bereich ermöglicht, einen Wert auszuwerten.


1
@ Doc: Unsinn. Das ist zunächst einmal nicht Standard C. Es wurde möglicherweise zu C ++ 0x hinzugefügt, ich weiß es nicht.
Oliver Charlesworth

13
@Doc Sie irren sich. Es ist nicht Standard C ++ und nicht Standard C. Es ist eine GCC-Erweiterung namens "Anweisungsausdruck".
Johannes Schaub - litb

Ich glaube nicht, dass es so ist. Visual Studio wird es sicherlich nicht akzeptieren.
Welpe

3
@mathepic: GCC ist anscheinend auch nicht (ohne die richtigen Optionen), daher die Frage und Verwirrung hier ...
Rubenvb
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.