Sto cercando di capire meglio come i compilatori producono codice per le espressioni indefinite ad es. per il seguente codice:Errore di assembler dell'espressione non definita
int main()
{
int i = 5;
i = i++;
return 0;
}
Questo è il codice assembler generato da gcc 4.8.2 (ottimizzazione è fuori -O0 e ho inserito i miei numeri di linea a fini di riferimento):
(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.
L'esecuzione di questo codice comporta il valore di i
rimanendo sul valore di (verificato con una dichiarazione printf()
), ovvero i
non sembra essere mai stato incrementato. Capisco che diversi compilatori valuteranno/compileranno espressioni indefinite in modi differnet e questo potrebbe essere solo il modo in cui gcc lo fa, cioè potrei ottenere un risultato diverso con un compilatore diverso.
Per quanto riguarda il codice assembler, se ho capito:
Ignorando linea - 1-2 creazione di puntatori dello stack/base, ecc linea 3/4 - è come viene assegnato il valore di a i
.
Qualcuno può spiegare cosa sta succedendo sulla linea 5-6? Sembra che i
sarà infine riassegnato il valore di (linea 7), ma è l'operazione di incremento (necessario per le operazioni post incremento i++
) semplicemente abbandonato/saltato dal compilatore nel caso?
Correlati: [punto di sequenza] (http://stackoverflow.com/q/3575350/2564301) – usr2564301