C11标准似乎暗示不应该优化具有常量控制表达式的迭代语句.我采纳了this answer的建议,它特别引用了标准草案中的6.8.5节:
其控制表达式不是常量表达式的迭代语句...可能会被执行机构假定为终止.
在这个答案中,它提到像while(1) ;
这样的循环不应该进行优化.
所以为什么Clang/LLVM优化了下面的循环(用cc -O2 -std=c11 test.c -o test
编译)?
#include <stdio.h>
static void die() {
while(1)
;
}
int main() {
printf("begin\n");
die();
printf("unreachable\n");
}
在我的机器上,这会打印出begin
,然后是crashes on an illegal instruction(die()
之后是ud2
).On godbolt,我们可以看到在调用puts
之后没有生成任何内容.
让Clang在-O2
以下输出一个无限循环是一项非常困难的任务——虽然我可以反复测试volatile
变量,但这涉及到我不想要的内存读取.如果我这样做:
#include <stdio.h>
static void die() {
while(1)
;
}
int main() {
printf("begin\n");
volatile int x = 1;
if(x)
die();
printf("unreachable\n");
}
...铿锵打印出begin
,然后是unreachable
,仿佛无限循环从未存在过.
如何让Clang在打开优化的情况下输出一个正确的无内存访问无限循环?