- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
C11 标准似乎暗示不应优化带有常量控制表达式的迭代语句。我正在接受 this answer 的建议,其中特别引用了标准草案中的第 6.8.5 节:
An iteration statement whose controlling expression is not a constant expression ... may be assumed by the implementation to terminate.
while(1) ;
这样的循环不应该进行优化。
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
,然后在非法指令上崩溃(一个
ud2
陷阱放在
die()
之后)。
On godbolt ,我们可以看到在调用
puts
之后没有生成任何东西.
-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
仿佛无限循环从未存在过。
最佳答案
C11 标准是这样说的,6.8.5/6:
An iteration statement whose controlling expression is not a constant expression,156) that performs no input/output operations, does not access volatile objects, and performs no synchronization or atomic operations in its body, controlling expression, or (in the case of a for statement) its expression-3, may be assumed by the implementation to terminate.157)
156) An omitted controlling expression is replaced by a nonzero constant, which is a constant expression.
157) This is intended to allow compiler transformations such as removal of empty loops even when termination cannot be proven.
while(1)
是一个非常清晰的常量表达式,因此实现可能不会假设它终止。这样的实现将无可救药地被破坏,因为“永远”循环是一种常见的编程结构。
-O3 -std=c11 -pedantic-errors
.LC0:
.string "begin"
main:
sub rsp, 8
mov edi, OFFSET FLAT:.LC0
call puts
.L2:
jmp .L2
-O3 -std=c11 -pedantic-errors
main: # @main
push rax
mov edi, offset .Lstr
call puts
.Lstr:
.asciz "begin"
#include <stdio.h>
#include <setjmp.h>
static _Noreturn void die() {
while(1)
;
}
int main(void) {
jmp_buf buf;
_Bool first = !setjmp(buf);
printf("begin\n");
if(first)
{
die();
longjmp(buf, 1);
}
printf("unreachable\n");
}
_Noreturn
试图帮助编译器进一步发展。应该很清楚,这个函数将挂断,仅从那个关键字。
setjmp
第一次执行时会返回 0,所以这个程序应该只是撞到
while(1)
并停在那里,只打印“开始”(假设\n 刷新标准输出)。这发生在 gcc 中。
关于c - 我如何制作一个不会被优化掉的无限空循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59925618/
我正在编写一个快速的 preg_replace 来从 CSS 中删除注释。 CSS 注释通常有这样的语法: /* Development Classes*/ /* Un-comment me for
使用 MySQL,我有三个表: 项目: ID name 1 "birthday party" 2 "soccer match" 3 "wine tasting evening" 4
我是一名优秀的程序员,十分优秀!