2010-03-03 10 views
8

Mögliche Duplizieren:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)Was wäre die Bewertungsreihenfolge von x = x ++ + ++ x; Sein?

In Java die Auswertung werden, um von links nach rechts angegeben ist. Gilt das auch für C und C++ oder ist es implementierungsabhängig? Ich erinnere mich, dass die Bewertungsreihenfolge für Funktionsargumente nicht spezifiziert ist, aber was ist mit Unterausdrücken? völlig undefiniertes Verhalten, aber das ist nicht einmal wichtig, weil in C und C++, ist das gleiche Objekt zweimal ohne eine dazwischenliegende Sequenz Punkt modifizieren -

+0

Duplikate: http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-iiiii-etc http://stackoverflow.com/questions/1826414/whats-the-value- von-ii-geschlossen http://stackoverflow.com/questions/1788696/how-the-code-behaves-different-for-java-and-c-compiler – bk1e

+18

lol. Der Mod Mod-schloss seine eigene Frage: D – Earlz

+3

@ bk1e: Danke für die Links. Ich hatte das Gefühl, dass dies hier schon früher behandelt wurde, aber es kam nicht auf, als ich die Frage stellte. Ich dachte, der schnellste Weg, das Original zu finden, wäre, einfach zu fragen. :) –

Antwort

13

Es ist nicht spezifiziert, welche der Argumente + zuerst ausgewertet wird.

Hier sind Sie xdrei mal ohne eine dazwischenliegende Sequenz Punkt zu modifizieren, so dass Sie auch abseits der Reservierung sind;)


Der relevante Teil des C99-Standard ist „6.5-Ausdrücke“:

2 zwischen dem vorherigen und nächsten Sequenzpunkt ein Objekt wird seinen gespeicherten Wert höchstens einmal durch die Auswertung eines modifizierten n Ausdruck. Außerdem muss der vorherige Wert Nur lesen sein, um den gespeicherten Wert zu ermitteln.

und

3 Die Gruppierung von Operatoren und Operanden wird durch die Syntax angegeben. Mit Ausnahme des später angegebenen (für den Funktionsaufruf(), & &, ||?,:, und Komma Operatoren), die Reihenfolge der Auswertung von Unterausdrücken und die Reihenfolge, in den Nebenwirkungen stattfinden sind beide nicht näher bezeichnet .


Es ist möglich, rechtlichen Code zu schreiben, die nicht spezifiziert Reihenfolge der Auswertung zeigt - zum Beispiel:

#include <stdio.h> 

int foo(void) 
{ 
    puts("foo"); 
    return 1; 
} 

int bar(void) 
{ 
    puts("bar"); 
    return 2; 
} 

int main() 
{ 
    int x; 

    x = foo() + bar(); 
    putchar('\n'); 

    return x; 
} 

(Es ist nicht spezifiziert, ob Sie die Ausgabe von foobar oder barfoo bekommen).

+0

Danke für die schnelle Antwort. –

2

Der C-Standard garantiert nicht, dass das Post-Inkrement tatsächlich nach dem Vorinkrement "passieren" wird. Das ist also undefiniertes Verhalten.

1

Das ist keine gültige C-Anweisung, daher macht es keinen Sinn, über die Evaluierungsreihenfolge zu sprechen.

+1

Was meinst du mit "gültig"? Es kompiliert erfolgreich in gcc und g ++. –

+4

Ob eine Datei erfolgreich von gcc kompiliert wurde, hat nichts damit zu tun, ob sie gültige C-Anweisungen enthält oder nicht. Der C-Standard bestimmt, was C gültig ist, nicht ein Compiler. –

+4

Diese Anweisung ist syntaktisch gültig, obwohl sie semantisch inkorrekt ist, da sie zu undefiniertem Verhalten führt. – qrdl

3

C++ 03 Standard 5.4

Soweit nicht anders angegeben, die Reihenfolge der Auswertung von Operanden einzelner Operatoren und Teilausdrücke von einzelnen Ausdrücke, und die Reihenfolge, in der Nebenwirkungen stattfinden, ist unspecified.53) zwischen dem vorherigen und der nächste Sequenzpunkt ein Skalar Objekt soll seinen gespeicherten Wert höchstens einmal durch die Auswertung eines Ausdrucks modifiziert haben. Außerdem muss der vorherige Wert sein, um nur den zu speichernden Wert zu ermitteln. Die Anforderungen dieses Abschnitts sind für jede zulässige Reihenfolge der Unterausdrücke eines vollständigen Ausdrucks zu erfüllen; andernfalls ist das Verhalten nicht definiert.

... daher, undefiniert und implementierungsabhängig.