2016-06-22 14 views
0

Ich habe einen Freund, die anderen Ausgang ist immer, als ich für das folgende Programm zu tun:Seltsam Nachinkrement Verhalten in C++

int main() { 
    int x = 20, y = 35; 
    x = y++ + x++; 
    y = ++y + ++x; 

    printf("%d%d", x, y); 

    return 0; 
} 

ich Ubuntu benutze und habe mit gcc und Klirren versucht. Ich bekomme 5693 von beiden.

Mein Freund verwendet Visual Studio 2015 und erhält 5794.

Die Antwort, die ich bekommen (5693) macht am meisten Sinn für mich, da:

  1. die erste Zeile setzt x = x + y (die x = 20+35 = 55 ist) (Anmerkung: x wurde erhöht, aber über oben zugewiesen, so doesn ‚t Angelegenheit)
  2. y wurde erhöht, und ist deshalb 36
  3. nächste Zeile erhöht sowohl das Ergebnis auf und legt es als y (die y = 37 + 56 = 93)
  4. die 56 und 93, wäre so die Ausgabe 5693

ist ich die VS Antwort macht Sinn, wenn die Post-Inkrement nach der Zuweisung geschehen sehen konnte. Gibt es eine Spezifikation, die eine dieser Antworten richtiger macht als die andere? Ist es nur zweideutig? Sollten wir jemanden entlassen, der einen solchen Code schreibt und die Mehrdeutigkeit irrelevant macht?

Hinweis: Zunächst haben wir nur mit gcc versucht, gibt jedoch Klirren diese Warnung:

[email protected]:~/playground$ clang++ strange.cpp 
strange.cpp:8:16: warning: multiple unsequenced modifications to 'x' [-Wunsequenced] 
    x = y++ + x++; 
     ~  ^
1 warning generated. 
+0

GCC [gibt mir Warnungen] (http://coliru.stacked-crooked.com/a/c7c7667511ece841). Stellen Sie sicher, dass Sie eine relativ aktuelle Version verwenden und Warnungen aktiviert haben. – chris

Antwort

1

Die Clang Warnung auf eine Klausel in der Standard-anspielt, C 11 ++ und später, dass es nicht definiert macht Verhalten, um zwei nicht sequenzielle Änderungen an demselben Skalarobjekt auszuführen. (In früheren Versionen des Standards war die Regel anders, obwohl sie ähnlich war.)

Die Antwort lautet also, dass die Spezifikation alle möglichen Antworten gleichermaßen gültig macht, einschließlich des Programmabsturzes; es ist in der Tat von Natur aus zweideutig. Natürlich hat Visual C++ in solchen Fällen ein etwas konsistentes und logisches Verhalten, obwohl der Standard es nicht benötigt: Es führt zuerst alle Vorinkremente durch, führt dann arithmetische Operationen und Zuordnungen aus und führt schließlich die Ausführung durch Alle Post-Inkremente, bevor Sie mit der nächsten Anweisung fortfahren. Wenn Sie den von Ihnen angegebenen Code verfolgen, werden Sie sehen, dass die Antwort von Visual C++ genau das ist, was Sie von diesem Verfahren erwarten würden.

+0

Was ich erwarte ist, was gcc und clang getan haben. Das Behandeln von '++' als f'n nimmt eine Referenz und gibt diesen Wert zurück (über eine Zwischenvariable temp), dann inzementiert der Wert an der Referenz für mich Sinn. Ich räume ein, dass Visual C++ konsistent ist und ich kann es interpretieren, aber ich mag es nicht. – CoatedMoose