2016-05-16 9 views
1

Warum wird die Funktion g() zuerst aufgerufen? Ich habe g() als das zweite Element in der Initialisierungsliste definiert.Bewertungsreihenfolge der Elemente in einer Initialisierungsliste

Ist das folgende Zitat aus der Norm zu Initialisiererlisten relevant?

§8.5.4.4: Innerhalb der Initialisierer-Liste einer verspannt-init-Liste, die initializer-Klauseln, jede einschließlich der (§14.5.3) aus Packungs Erweiterungen resultieren, werden in der Reihenfolge ausgewertet in dem sie erscheinen.

#include <iostream> 
#include <vector> 

int f() { std::cout << "f"; return 0;} 
int g() { std::cout << "g"; return 0;} 

void h(std::vector<int> v) {} 

int main() { 

    h({f(), g()}); 
} 

Ausgang:

gf 
+4

Ihr Code enthält keine Initialisierungslisten. –

+3

Evaluierungsreihenfolge der Funktionsparameter ist in C++ nicht angegeben. – 101010

+0

http://stackoverflow.com/questions/621542/compilers-and-argument-order-of-evaluation-in-c –

Antwort

0

Es scheint mir, dass das Zitat relevant ist (der Compiler sieht eine Initialisiererliste):

8,5/14, 16:

Die Initialisierung erfolgt in der Form

T x = a;

sowie in Argument Übergabe, Funktion zurückgeben, eine Ausnahme (15.1), eine Ausnahme (15.3), und Aggregat-Element-Initialisierung (8.5.1) zu behandeln heißt copy-Initialisierung.

.

.

Die Semantik der Initialisierer ist wie folgt [...]: Wenn der Initialisierer eine brained-init-Liste ist, wird das Objekt in der Liste initialisiert (8.5.4).

(weitere Details in std::initializer_list as function argument und Folds (ish) In C++11)

Darüber hinaus jede {} -Liste soll (der Standard verwendet eine sehr starke Formulierung über diese Tatsache. Siehe auch http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1030) sequenziert werden.

So ist es probably a GCC bug (behoben nach gcc v4.9.0).

der Tat verschiedene GCC-Version versuchen, erhalte ich:

GCC  with --std=c++11 without (--std=c++98) 
4.7.3  fg     gf <- 
4.8.1  fg     gf <- 
4.8.2  fg     gf <- 
4.9.0  fg     gf <- 
4.9.2  fg     fg 
5.1.0  fg     fg 
5.2.0  fg     fg 
6.1.0  fg     fg 

Erweiterte initializer Listen nur verfügbar sind, mit 11 C++, aber GCC kompiliert den Code sowieso (mit einer Warnung, siehe beispielsweise gcc -Wall -Wextra vs gcc -Wall -Wextra -std=c++11).

+0

betrachte editierten Beitrag – Adib

+0

ich versuchte In jedem Fall ist das Ergebnis dasselbe Problem --std = C++ 11 – Adib

+0

@ user5905343 Leider gcc v4.8.4 fehlt auf https://gcc.godbolt.org aber unter Berücksichtigung der oben genannten Tests scheint es ein Fehler. – manlio

2

Dies ist keine braced-init-Liste, so dass die Regel nicht gilt.

[C++14: 5.17/9]: A verspannt-init-Liste auf der rechten Seite von

  • eine Zuordnung zu einem skalaren erscheinen können, in welchem ​​Fall die Initialisiererliste höchstens einem einzelnen Element haben soll. Die Bedeutung von x={v}, wobei T der Skalartyp des Ausdrucks x ist, ist der von x=T{v}. Die Bedeutung von x={} ist x=T{}.
  • eine Zuweisung zu einem Objekt des Klassentyps. In diesem Fall wird die Initialisierungsliste als Argument an die Funktion des Zuweisungsoperators übergeben, die durch die Überladungsauflösung (13.5.3, 13.3) ausgewählt wurde.
+0

Wahrscheinlich irre ich mich, aber eine * braced-init-Liste * kann in vielen anderen Kontexten auftreten: z.B. * for-range-initializer * ('für (for-range-declaration: braced-init-list) Anweisung', §6.5.4), * jump-statements * (' return braced-init-list; ', §6.6), ... – manlio

+0

@manlio: Meh, okay gut, ich habe versucht, den Beweis zu finden, dass _dieser Fall keine _spraceed-init-list_ enthält (was eine viel bessere Antwort wäre), aber schlussfolgerte, dass ich zu viel zitieren müsste. –

+0

Berücksichtigt auch [std :: initializer_list als Funktionsargument] (http://stackoverflow.com/q/2357452/3235496) und insbesondere die [diese Antwort] (http://stackoverflow.com/a/2357688/3235496), Argumentübergabe soll die gleiche Bedeutung haben wie '= Initialisierer (beides ist Kopierinitialisierung). Also ist diese Kopierinitialisierung nicht (Objekt * list-initialisiert * via * braced-init-list *)? – manlio

Verwandte Themen