2010-11-22 6 views
7

Ja, ich habe den Artikel auf sequence points gelesen. Ich konnte jedoch nicht verstehen, warum ++i = 2 undefiniertes Verhalten aufrufen würde? Der endgültige Wert von i wäre 2 unabhängig von irgendetwas, also wie kommt der Ausdruck ub?Noch eine Frage zu den Sequenzpunkten

Code-Schnipsel

int main() 
{ 
    int i =0; 
    ++i=2; 
    return 0; 
} 

Leider ist mein Englisch nicht sehr gut.

Antwort

9

Sie beobachten dieser Wert wird sein, was Sie behaupten, so kann sich UB unter anderen möglichen Szenarien manifestieren. Das Programm gibt möglicherweise aus, was Sie erwarten, gibt einige nicht verwandte Daten aus, stürzt ab, beschädigt Daten oder gibt Ihr ganzes Geld aus, um Pizza zu bestellen. Sobald der C++ - Standard sagt, dass ein Konstrukt UB ist, sollten Sie kein spezifisches Verhalten erwarten. Beobachtete Ergebnisse können von einem Programmlauf zum anderen variieren.

+0

aber wie könnte das Ergebnis von 2 abweichen? Ich habe versucht, ein paar Online-und Offline-Compiler einschließlich gcc, msvC++, Intel C++. Ich habe nichts anderes als 2. – AMS

+1

@AMS: Was ist, wenn das Programm auch Ihr ganzes Geld ausgegeben oder alle Ihre Passwörter an eine dritte Partei (http://stackoverflow.com/questions/908872/whats-the-worst-example-) of-undefined-Verhalten-eigentlich-möglich/3554343 # 3554343)? – sharptooth

+0

Und das ist überhaupt kein Witz - ich ermutige Sie, dem Link tatsächlich zu folgen und die Antwort dahinter zu lesen. – sharptooth

0

aus exakt den gleichen Link, den Sie bieten:

  • Darüber hinaus wird der Stand der Wert nur den Wert bestimmen zugegriffen werden gespeichert werden.

Was bedeutet das? Das heißt, wenn ein -Objekt in einen vollständigen -Ausdruck geschrieben wird, müssen alle Zugriffe darauf innerhalb desselben Ausdrucks direkt in die Berechnung des zu schreibenden Werts einbezogen werden.

hier auf der linken Seite des Operators =, wird der Zugriff auf i nicht geschrieben in der Berechnung des Wertes beteiligt.

0

++ ich (sollte) ein rvalue, und kann daher nicht als lvalue verwendet werden, aber (++ i) = 2; sollte gut funktionieren. Ich glaube nicht, dass das UB ist, aber wie immer könnte ich mich irren.

+0

Ja, Sie liegen falsch. Durch das Hinzufügen von Klammern wird das Parsen dieses Ausdrucks nicht geändert. Der Präfixoperator ++ gibt einen Lvalue zurück. Das UB ist ein Ergebnis des zweimaligen Schreibens desselben lvalue im selben Sequenzpunkt. –

+0

@Greg Rogers: Danke! –

11

Es sieht offensichtlich zu Ihnen, weil offensichtlichi wird erstei+1, dann zweite den 2 Wert zugewiesen werden zugewiesen werden.

jedoch passieren diese beiden Aufgaben innerhalb derselben Sequenz Punkt, daher liegt es an den Compiler, auf die frist geschieht und die zweite geschieht, damit unterschiedliche Compiler-Implementierungen kann Code generieren, die unterschiedliche Ergebnisse liefern, deshalb ist es UB .

+4

Yeap, und auch der Compiler ist nicht erforderlich, um das gleiche Programm in verschiedenen Compiles zu erzeugen. Druckt 0 bei einem Kompilieren, löscht einen Datenträger auf einem anderen. – sharptooth

1

Der Aufruf ++i = 2; ruft an und für sich kein undefiniertes Verhalten auf; Jeder Compiler kann, wenn er will, beim Erreichen dieses Codes eine sehr definierte Aktion ausführen. Der C++ - Standard besagt jedoch, dass eine solche Operation nicht definiert ist. Daher kann ein Compiler etwas Unerwartetes tun (z. B. alle Dateien auf dem C-Laufwerk löschen oder eine Textnachricht an den Papst senden) und trotzdem ein kompatibler Compiler sein. Das einzige, was diese UB macht ist, dass der Standard sagt, dass es UB ist.

Der vielleicht wichtigste Punkt ist, dass eine Version eines Compilers etwas anderes als die nächste Version desselben Compilers tun kann.

2

Das undefinierte Verhalten tritt auf, weil ein Compiler den folgenden Code implementieren könnte:

++i = 2; 

als entweder:

i = 2; 
++i; 

oder

++i; 
i = 2; 

nicht spezifiziert Es ist in der Sprache, ein Compiler könnte entscheiden, eines der oben genannten zu implementieren. Die erste würde 3 und die zweite 2 produzieren. Es ist also undefiniert.