Unterschiedliches Verhalten des Schichtoperators mit -O2 und ohne

8

Ohne -O2 gibt dieser Code 84 84 aus, mit O2-Flag ist die Ausgabe 84 42 . Der Code wurde mit gcc 4.4.3. auf einer 64-Bit-Linux-Plattform kompiliert. Warum ist die Ausgabe für den folgenden Code anders?

Beachten Sie, dass bei der Kompilierung mit -Os die Ausgabe 0 42

ist %Vor%     
Leonid 04.03.2011, 15:29
quelle

3 Antworten

19

Wenn Sie die Optimierung mit gcc verwenden, können bestimmte Annahmen basierend auf dem Typ der Ausdrücke verwendet werden, um unnötige Lesevorgänge zu vermeiden und das Speichern von Variablen im Speicher zu ermöglichen.

Ihr Code hat ein undefiniertes Verhalten, weil Sie einen Zeiger auf ein long long (das gcc als Erweiterung erlaubt) auf einen Zeiger auf ein int umwandeln und dann das pointed-to-object so manipulieren, als wäre es ein int . Ein Zeiger auf int kann normalerweise nicht auf ein Objekt vom Typ long long zeigen, so dass gcc annehmen darf, dass eine Operation, die in einen int (über einen Zeiger) schreibt, kein Objekt vom Typ% beeinflusst. co_de%.

Es ist daher legitim, den Wert von long long zwischen dem Zeitpunkt, an dem er ursprünglich zugewiesen wurde, und dem Zeitpunkt, zu dem er anschließend gedruckt wird, zwischenzuspeichern. Keine gültige Schreiboperation könnte ihren Wert geändert haben.

Der zu lesende Schalter und die Dokumentation sind n .

    
Charles Bailey 04.03.2011, 15:37
quelle
6

Sie brechen striktes Aliasing. Kompilieren mit -Wall sollte Ihnen eine dereferencing type-punned pointer Warnung geben. Siehe z.B. Ссылка

    
Erik 04.03.2011 15:38
quelle
1

Ich bekomme die gleichen Ergebnisse mit GCC 4.4.4 unter Linux / i386.

Das Verhalten des Programms ist nicht definiert, da es die strenge Aliasing-Regel verletzt.

    
Fred Foo 04.03.2011 15:39
quelle