据说无限循环for(;;);
是未定义的行为。
来自http://en.cppreference.com/w/cpp/language/memory_model
在一个有效的C ++程序中,每个线程最终会执行其中一个 以下内容:
- 终止
- 调用I / O库函数
- 读取或修改易失性对象
- 执行原子操作或同步操作
没有执行任何操作,任何执行线程都不能永久执行 这些可观察的行为。
请注意,这意味着程序具有无限递归或无穷无尽 循环(无论是作为for语句实现还是通过循环goto或 否则)有不确定的行为。
但是如果它在共享库中调用一个函数呢?
for(;;) sofunc();
该函数可以执行任何类型的阻塞I / O或抛出异常。
在这种情况下,编译器是否认为循环有一些可观察的行为?
答案 0 :(得分:3)
有许多地方标准的语言使编制者的自由超出了有用优化所需的自由,但这会为编制者提供将窗口中最小惊讶原则抛到窗外的方法。关于无限循环的规则的编写方式符合该类别。
有关无限循环的规则将促进的大多数优化都将通过语言来启用,该语言指定执行一段代码所需的时间,即使无限,也不被认为是是编译器需要保留的副作用。这样的规则将允许编译器省略任何没有任何直接副作用的循环迭代,并且不会修改在别处使用的值。
然而,标准不仅限于此。鉴于代码:int foo(void)
{
int x=0;
do
{
x=functionWithNoSideEffects(x);
} while(x != 23 && x != 42);
return x;
}
一个可以显示functionWithNoSideEffects永远不会有的编译器 任何已定义的副作用并且永远不会返回23可以用“return 42;”替换“foo”的代码。即使程序的目的是测试functionWithNoSideEffects是否会返回42(在这种情况下生成的代码返回42,无论函数是否有用)标准都不需要编译器生成代码来实际测试它,除非循环包括某种“副作用”。
我个人并不相信拥有一条规则的价值 如果编译器可以显示循环不能在没有X的情况下终止,那么它们 可以认为X是否为真,无论是否有任何方法 可能。然而,基于该原则的优化似乎很受欢迎。