为什么不用汇编来确定这个问题呢?
结论:本地变量只会被声明一次;然而,每次都会执行所有赋值操作。
下面是证明。
我简化了这个问题:
main.cpp:
int f() {
begin:
int i = 0;
if (i == 0)
{
i++;
goto begin;
}
return i + 2;
}
int main()
{
int i = f();
return i;
}
然后我使用以下命令在Linux上将其编译为汇编代码(取消注释asm
):
g++ -std=c++20 -I/usr/include/c++/11 -I/usr/include/x86_64-linux-gnu/c++/11 -S main.cpp
这个命令会生成main.s文件,它是main.cpp的汇编输出。以下是相关部分;我添加了一堆破折号以使其更明显:
#APP
# 2 "main.cpp" 1
-----------------------------------
# 0 "" 2
# 4 "main.cpp" 1
-----------------------------------
# 0 "" 2
#NO_APP
.L2:
movl $0, -4(%rbp)
cmpl $0, -4(%rbp)
jne .L3
addl $1, -4(%rbp)
jmp .L2
.L3:
#APP
# 13 "main.cpp" 1
-----------------------------------
# 0 "" 2
#NO_APP
movl -4(%rbp), %eax
addl $2, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size _Z1fv, .-_Z1fv
.globl main
.type main, @function
main:
.LFB1:
.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
#APP
# 19 "main.cpp" 1
-----------------------------------
# 0 "" 2
#NO_APP
call _Z1fv
movl %eax, -4(%rbp)
#APP
# 21 "main.cpp" 1
-----------------------------------
然后,我使用以下命令编译main.cpp:
g++ -std=c++20 -I/usr/include/c++/11 -I/usr/include/x86_64-linux-gnu/c++/11 main.cpp -omain
编译成功。 然后我运行它:
./main
但是它一直卡在无限循环中。
a
是类类型,那么在它之前跳转会调用它的析构函数。所以我想知道如果它是非类类型,那么在它之前跳转是否会使其值无效?所以跳转到z
,然后到u
,a
的值是否仍为10
,或者可能是由局部变量或某些汇编操作在点z
处使用的随机其他值? - Johannes Schaub - litb