在C语言中,我想获取一个标签的地址,找到了如下方法: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
但是,由于我的代码中存在 goto 语句,发生了奇怪的事情: https://godbolt.org/z/P88MrY5re
#include <string.h>
#include <stdio.h>
int main(){
void *p = &&aa;
printf("hello, never execute\n");
goto end;
aa:
printf("new path\n");
end:
printf("end\n");
return 0;
}
这是汇编代码:
.LC0:
.string "hello, never execute"
.LC1:
.string "end"
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
.L2:
movq $.L2, -8(%rbp)
movl $.LC0, %edi
call puts
nop
movl $.LC1, %edi
call puts
movl $0, %eax
leave
ret
当我注释掉goto语句时,我正确获取了标签aa的地址: https://godbolt.org/z/P88MrY5re
#include <string.h>
#include <stdio.h>
int main(){
void *p = &&aa;
printf("hello, never execute\n");
//goto end;
aa:
printf("new path\n");
end:
printf("end\n");
return 0;
}
.LC0:
.string "hello, never execute"
.LC1:
.string "new path"
.LC2:
.string "end"
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movq $.L2, -8(%rbp)
movl $.LC0, %edi
call puts
.L2:
movl $.LC1, %edi
call puts
movl $.LC2, %edi
call puts
movl $0, %eax
leave
ret
因此,我想知道当有 goto 语句时,编译器是否已经删除了标签
aa
。我觉得代码void *p = &&aa;
不应该编译。这是 gcc 中的错误,还是有什么我没有考虑到的?
我查阅了一些资料,也询问了周围的人,但都没有得到我想要的答案。我想知道这是否算作 gcc 中的错误,或者您能为我提供一些资源或想法吗?
谢谢大家!
虽然编译器确实优化了对
printf("new path\n");
的调用,但它并没有完全删除所有内容。 您会注意到第一个 call puts
指令之后是 nop
。 这就是标签所指向的指令。
此外,如果代码由于打开优化而无法编译,则可能会导致优化器存在错误,因为优化不应影响代码的可观察行为。