我们以下面这么一段代码开始
void test_inc() { int i = 10; i = i++; printf("i = %d\n", i); }
运行输出
i = 10
看起来出乎意料,来我们看看他编译之后的汇编代码就明白了
test_inc: .LFB20: .cfi_startproc endbr64 pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movl $10, -4(%rbp) movl -4(%rbp), %eax leal 1(%rax), %edx movl %edx, -4(%rbp) movl %eax, -4(%rbp) movl -4(%rbp), %eax movl %eax, %esi leaq .LC11(%rip), %rdi movl $0, %eax call printf@PLT nop leave .cfi_def_cfa 7, 8 ret .cfi_endproc
可以看出i++的流程是这样的
R1 = i;
R2 = R1 + 1;
i = R2;
i = R1;
这就可以解释i的值最终没有变化。
所以编译器编译后产生的指令流程是先把+1后的值写回i,然后又把+1之前暂存在寄存器里的i的值赋值给i。i的值先变成11,然后又变回10了。