Ich versuche, ein besseres Verständnis von, wie Compiler Code für undefined Ausdrücke z. für den folgenden Code:Assembler Debug von undefiniertem Ausdruck
int main()
{
int i = 5;
i = i++;
return 0;
}
Dies ist der von gcc erzeugt Assembler-Code 4.8.2 (Optimierung off -O0 ist, und ich habe meine eigenen Zeilennummern für Referenzzwecke eingesetzt):
(gdb) disassemble main
Dump of assembler code for function main:
(1) 0x0000000000000000 <+0>: push %rbp
(2) 0x0000000000000001 <+1>: mov %rsp,%rbp
(3) 0x0000000000000004 <+4>: movl $0x5,-0x4(%rbp)
(4) 0x000000000000000b <+11>: mov -0x4(%rbp),%eax
(5) 0x000000000000000e <+14>: lea 0x1(%rax),%edx
(6) 0x0000000000000011 <+17>: mov %edx,-0x4(%rbp)
(7) 0x0000000000000014 <+20>: mov %eax,-0x4(%rbp)
(8) 0x0000000000000017 <+23>: mov $0x0,%eax
(9) 0x000000000000001c <+28>: pop %rbp
(10) 0x000000000000001d <+29>: retq
End of assembler dump.
Die Ausführung dieses Codes führt dazu, dass der Wert i
auf dem Wert bleibt (verifiziert mit einer printf()
-Anweisung), dh i
scheint nicht inkrementiert zu werden. Ich verstehe, dass verschiedene Compiler nicht definierte Ausdrücke auf unterschiedliche Weise auswerten/kompilieren werden und dies kann einfach die Art sein, wie gcc das tut, d.h. ich könnte ein anderes Ergebnis mit einem anderen Compiler bekommen.
Im Hinblick auf die Assembler-Code, wie ich sie verstehe:
Ignorieren line - 1-2 up-Stack/Basiszeiger Einstellung usw. Linie 3/4 - ist, wie der Wert von zugeordnet ist zu i
.
Kann jemand erklären, was in Zeile 5-6 passiert? Es sieht so aus, als ob i
schließlich der Wert von (Zeile 7) neu zugewiesen wird, aber ist die Inkrementierung (erforderlich für die Post-Inkrement-Operation i++
) einfach vom Compiler in dem Fall aufgegeben/übersprungen?
Verwandte: [Sequenzpunkt] (http://Stackoverflow.com/q/3575350/2564301) – usr2564301