Ist dieser Code gut definiert?

8

Ich vermute, dass die folgende Verkettung von Funktionen zu einer nicht spezifizierten Sequenz gemäß den C ++ - Standards führen würde (angenommen, C ++ 0x). Ich möchte nur eine Bestätigung und wenn jemand eine Erklärung geben könnte, würde ich es zu schätzen wissen.

%Vor%

* edit: entfernt __fastcall specifier für Funktionen (nicht erforderlich / relevant für die Frage).

    
Zach Saw 14.07.2011, 01:03
quelle

2 Antworten

8

Die Bewertungsreihenfolge wurde nicht angegeben. Der relevante Abschnitt des Entwurfs C ++ 0x Spezifikation ist 1.9, Absätze 14 und 15:

  

14 Jede mit einem full-expression verknüpfte Wertberechnung und Nebenwirkung wird vor jeder Wertberechnung und jedem Nebeneffekt, der mit dem nächsten auszuwertenden Vollwert verknüpft ist, sequenziert.

     

15 Sofern nicht anders vermerkt, sind Auswertungen von Operanden einzelner Operatoren und von Teilausdrücken einzelner Ausdrücke nicht sequentiell.

Hier ist der relevante vollständige Ausdruck :

%Vor%

Und so ist die Auswertung seiner Teilausdrücke nicht geordnet (außer es gibt eine Ausnahme, die ich irgendwo vermerkt habe).

Ich bin mir ziemlich sicher, dass frühere Standards Sprache mit dem gleichen Effekt, aber in Bezug auf "Sequenzpunkte" enthalten.

[Bearbeiten]

In Absatz 15 heißt es auch:

  

Beim Aufrufen einer Funktion (unabhängig davon, ob die Funktion inline ist oder nicht) werden alle Werteberechnungen und Nebeneffekte eines beliebigen Argumentausdrucks oder des Postfixausdrucks, der die aufgerufene Funktion bezeichnet, vor der Ausführung jedes Ausdrucks oder jeder Anweisung in der Sequenz sequenziert Körper der aufgerufenen Funktion. [Anmerkung: Wertberechnungen und Nebenwirkungen, die mit verschiedenen Argumentausdrücken verbunden sind, sind nicht sequenziert.- Endnote]

Ein "postfix-Ausdruck, der die aufgerufene Funktion bezeichnet" ist etwas wie die foo().bar in foo().bar() .

Die "Anmerkung" stellt hier lediglich klar, dass die Argumentauswertungsreihenfolge nicht ist, eine Ausnahme von der "nicht spezifizierten Reihenfolge". Durch Rückschluss ist auch die Bewertungsreihenfolge dem "Postfix-Ausdruck, der die aufgerufene Funktion bezeichnet" zugeordnet; oder wenn Sie bevorzugen, die Bewertungsreihenfolge des Ausdrucks für das Argument this . (Wenn es eine Ausnahme gäbe, wäre dies der natürliche Ort, um sie zu spezifizieren. Oder möglicherweise Abschnitt 5.2.2, der über Funktionsaufrufe spricht. Keiner der Abschnitte sagt etwas über die Bewertungsreihenfolge für dieses Beispiel aus, so dass er nicht spezifiziert ist.)

    
Nemo 14.07.2011, 01:24
quelle
1

Ja, die Reihenfolge der Auswertung von Funktionsargumenten ist nicht spezifiziert.

Für mich produziert gcc 4.5.2 unter linux

%Vor%

aber clang ++ auf linux und gcc 3.4.6 auf solaris produzieren

%Vor%

Um ein einfacheres Beispiel zu analysieren, ist TFoo(0).foobar1(TFoo::bar2()); ein Aufruf von TFoo::foobar1 , der zwei Argumente benötigt: das Ergebnis des Teilausdrucks TFoo(0) (als verstecktes Argument this ) und das Ergebnis des Teilausdrucks Tfoo::bar2() . Für mich führt gcc zuerst bar2() , dann TFoo's Konstruktor und dann foobar1() aus, während clang ++ zum Beispiel TFoo's Konstruktor zuerst ausführt, dann bar2() und dann foobar1() aufruft.

    
Cubbi 14.07.2011 01:23
quelle