goo b = { f(), g() };
goo c { f(), g() }; /* C++11 */
die Auswertungsreihenfolge wird von links nach rechts bestimmt und alle Nebeneffekte sollen vor dem nächsten Initialisierer angewendet werden.
Aus dem C++-STANDARD
4 Innerhalb der Initialisierungsliste einer geklammerten Initialisierungsliste werden die Initialisierungsklauseln, einschließlich aller, die aus Paketerweiterungen (14.5.3) resultieren, in der Reihenfolge ausgewertet, in der sie erscheinen. Das heißt, jede Wertberechnung und Nebenwirkung, die einer gegebenen Initialisierungsklausel zugeordnet ist, wird vor jeder Wertberechnung und Nebenwirkung geordnet, die irgendeiner Initialisierungsklausel zugeordnet ist, die ihr in der durch Kommas getrennten Liste der Initialisierungsliste folgt.
In C gibt es jedoch eine andere Regel
Die Auswertungen der Initialisierungslistenausdrücke sind in Bezug aufeinander unbestimmt sequenziert, und somit ist die Reihenfolge, in der irgendwelche Nebeneffekte auftreten, unbestimmt.
Wenn ich darüber nachdenke, denke ich, dass alle bis auf die letzten in C ++ 11 so sind.
– Chris
19. März 2014 um 19:09 Uhr
@Vlad: Was ist mit den ersten beiden Zeilen in C++11? Die Reihenfolge steht nicht fest?
– Benutzer1150105
19. März 2014 um 19:18 Uhr
@Corvus Der erste Ausdruck int a[] = {f(), g()}; erfüllt die Regel. Berücksichtigen Sie, dass GCC 4,8,2 einen Fehler hat. Der zweite Ausdruck soll nicht kompiliert werden.:) Es gibt keinen Deklarator.
– Vlad aus Moskau
19. März 2014 um 19:21 Uhr
@Vlad: Entschuldigung für den zweiten Ausdruck. Ich habe es bearbeitet.
– Benutzer1150105
19. März 2014 um 19:32 Uhr
@hackks: Welche Regel macht es bestimmt? goo ddie keine geklammerte Init-Liste hat?
– Ben Voigt
19. März 2014 um 20:27 Uhr
hackt
Ist die Ausführungsreihenfolge f() und g() in irgendeiner Zeile durch C- und C++-Standards spezifiziert?
In C, Nein. Sie können in beliebiger Reihenfolge auswerten.
C11 6.7.9 Initialisierung
Die Auswertungen der Initialisierungslistenausdrücke sind in unbestimmter Reihenfolge zueinander und damit Die Reihenfolge, in der Nebenwirkungen auftreten, ist nicht angegeben,152).
Während C++11 sagt, dass die Reihenfolge der Auswertung deterministisch ist.
8.5.4:4 Listen-Initialisierung
Innerhalb der Initialisierungsliste einer geklammerten Initialisierungsliste werden die Initialisierungsklauseln, einschließlich aller, die aus Paketerweiterungen (14.5.3) resultieren, werden in der Reihenfolge ihres Erscheinens ausgewertet. Das heißt, jede Wertberechnung und Nebenwirkung, die einer gegebenen Initialisierungsklausel zugeordnet ist, wird vor jeder Wertberechnung und Nebenwirkung geordnet, die irgendeiner Initialisierungsklausel zugeordnet ist, die ihr in der durch Kommas getrennten Liste der Initialisierungsliste folgt.
152) Insbesondere muss die Auswertungsreihenfolge nicht dieselbe sein wie die Reihenfolge der Unterobjektinitialisierung.
Wo sind f und g definiert? Ich sehe es nicht
– Ingenieur2021
19. März 2014 um 19:04 Uhr
@GIJoe; Angenommen, der bereitgestellte Code ist nur ein Code-Snippet 🙂
– Hacken
19. März 2014 um 19:06 Uhr
Könnte evtl. an den fehlenden Hinweisen und der Kürze der Antwort liegen.
– Manu343726
19. März 2014 um 19:13 Uhr
@Convus das ist nicht sein Problem, denke ich. Das ist das Problem eines OP, weil diese Art von Frage für verschiedene Sprachen getaggt wird (möglicherweise denken, dass C und C ++ dieselbe Sprache sind).
– Manu343726
19. März 2014 um 19:20 Uhr
Aber der Initialisierer von goo d hat keine geklammerte Init-Liste, daher gilt für diese die zitierte C++-Regel nicht.
– Ben Voigt
19. März 2014 um 20:27 Uhr
ouah
Nein, in C ist die Auswertungsreihenfolge der Initialisierer nicht festgelegt:
(C11, 6.7.9p23) “Die Auswertungen der Initialisierungslistenausdrücke sind in unbestimmter Reihenfolge zueinander und daher ist die Reihenfolge, in der irgendwelche Seiteneffekte auftreten, nicht spezifiziert.152)”
152) Insbesondere muss die Auswertungsreihenfolge nicht dieselbe sein wie die Reihenfolge der Unterobjektinitialisierung.
In C++ ist das Verhalten anders, und die Initialisierer werden in der Reihenfolge ausgewertet, in der sie erscheinen (C++11, 8.5.4p4).
iavr
In C++11 ist der relevante Teil Absatz 4 von 8.5.4 Listen-Initialisierung
Innerhalb der Initialisierungsliste von a geklammerte Init-Listedas Initialisierungsklauselneinschließlich aller, die aus Paketerweiterungen (14.5.3) resultieren, werden in der Reihenfolge ihres Erscheinens ausgewertet. Das heißt, jede Wertberechnung und Nebenwirkung, die mit einer bestimmten verbunden ist Initialisierungsklausel vor jeder Wertberechnung sequenziert und mit irgendeiner Nebenwirkung verbunden ist Initialisierungsklausel das folgt in der durch Kommas getrennten Liste der Initialisierungsliste. [ Note: This evaluation ordering holds regardless of the semantics of the initialization; for example, it applies when the elements of the initializer-list are interpreted as arguments of a constructor call, even though ordinarily there are no sequencing constraints on the arguments of a call. — end note ]
Die Reihenfolge der Bewertung ist also links nach rechts.
Jedoch Beachten Sie, dass leider aufgrund von a Insekt seit mindestens Version 4.7.0 wertet GCC in umgekehrter Reihenfolge aus, rechts nach links. Wenn Sie also unerwartete Ergebnisse erhalten, kann dies ein Grund sein.
11754400cookie-checkBestellen einer Initialisierung in C, C++yes
Obligatorischer cppquiz-Link
– Chris
19. März 2014 um 19:15 Uhr