在 C++ 中循环为
for(;;) {}
是UB,而不是C?
在 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2809r0.html 中表示这样做有“充分的理由”。有没有简单的例子可以清楚地说明这一点?
如果编译器可以假设所有循环都终止,则不必证明这一点。
如果允许非终止循环,则只有在能够证明终止的情况下才允许编译器执行某些优化,这通常是不可能的,因此它会变成模式识别游戏。为了什么好处?
根本问题是非终止本身是一种副作用。当且仅当循环终止时,才会观察到循环终止后肯定会发生的任何可观察到的效果,即使循环没有效果. 获取以下代码。
int collatz_conjecture(int i){
while(i!=1){
if ((i%2)==0)
i/=2;
else
i=i*3+1;
}
return i;
}
int main(){
collatz_conjecture(10);
return 5;
}
使用 O3,gcc 将其编译为:
collatz_conjecture(int):
mov eax, 1
ret
main:
mov eax, 5
ret
那么,编译器是否证明了 Collatz 猜想才能确定它可以返回
5
?当然不是,它忽略了它。
更有用的例子可以是交错复制。如果你有loop A
loop B
即使不知道
A
终止,编译器也可以交错它们。许多矢量化操作都依赖于这个假设。
类似地,在循环之前重新排序一些独立的循环后操作会假定循环将终止。