当我尝试编译并执行以下代码时
#include <stdio.h>
int main()
{
int a = 5;
printf("%d %d",--a,++a);
return 0;
}
我得到的输出是5 5
根据一般理解,输出应为5 6
。所以我在编译器中有一个可疑之处,并使用以下命令生成了程序集
gcc -S <my program>
当我分析装配时,发现我的嫌疑犯是正确的。请参见下面的汇编代码。
.file "inc_dec.c"
.section .rodata
.LC0:
.string "%d %d"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $5, -4(%rbp)
addl $1, -4(%rbp)
subl $1, -4(%rbp)
movl -4(%rbp), %edx
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section .note.GNU-stack,"",@progbits
编译器的实际作用是。首先将value(5)推送到寄存器地址(rbp-4)。然后,它先执行减法和加法指令,然后将值作为参数推入printf。所有这些之后,它称为printf。
因此,变量a变为5,递增时变为6,递减时变为5,然后为printf的两个参数推送a的值。
因此,产生的是5 5
而不是6 5
或5 6
。
即使我尝试通过-o0
禁用优化,并将变量命名为volatile
。结果还是一样。
我的问题是为什么会这样发生?如何避免这种情况?