Ich habe folgenden Code:
#include <stdio.h>
int main(int argc, char **argv) {
int i = 0;
(i+=10)+=10;
printf("i = %d\n", i);
return 0;
}
Wenn ich versuche, es mit gcc als C-Quelle zu kompilieren, wird folgende Fehlermeldung angezeigt:
error: lvalue required as left operand of assignment
Aber wenn ich es als C ++ - Quelle mit g ++ kompiliere, erhalte ich keine Fehlermeldung und wenn ich die ausführbare Datei ausführe:
i = 20
Warum das unterschiedliche Verhalten?
Antworten:
Die Semantik der zusammengesetzten Zuweisungsoperatoren unterscheidet sich in C und C ++:
C99 Standard, 6.5.16, Teil 3:
In C ++ 5.17.1:
BEARBEITEN: Das Verhalten von
(i+=10)+=10
in C ++ ist in C ++ 98 undefiniert, in C ++ 11 jedoch gut definiert. In dieser Antwort auf die Frage von NPE finden Sie die relevanten Teile der Standards.quelle
(i+=10)+=10
es sich in C ++ um ein undefiniertes Verhalten handelt, siehe @ aix-Antwort.int f(int &y); f(x += 10);
Übergeben eines Verweises auf die geänderte Variable an eine Funktion nützlich gewesen .Zusätzlich zum ungültigen C-Code ist die Zeile
würde sowohl in C als auch in C ++ 03 zu einem undefinierten Verhalten führen, da es
i
zwischen Sequenzpunkten zweimal geändert würde .Warum es in C ++ kompiliert werden darf:
Im selben Absatz heißt es weiter
Dies deutet darauf hin, dass der Ausdruck in C ++ 11 kein undefiniertes Verhalten mehr aufweist.
quelle
i
sequenziert wurden.i = j+=1
wäre, würde dies zu einem unbestimmten Wert führen. Aus demselben Absatz zitieren Sie "In allen Fällen wird die Zuweisung nach der Wertberechnung des rechten und linken Operanden und vor der Wertberechnung des Zuweisungsausdrucks sequenziert." Daher(i+=10)+=10
ist gut definiert zu tuni += 10; i += 10;
. Auf der anderen Seite(i+=10)+=(i+=10)
ist UB.