我们以下面这么一段代码开始
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了。
浙公网安备 33010602011771号