在C++ 11中,它是未定义的行为,但在C中的情况while(1);是未定义的行为吗?
考虑简单的代码:
#include "stdio.h"
#define N 10U
int main() {
int a[N] = {0};
unsigned int i = N;
int s = 0;
// Fill a
while(i--)
s += a[i];
printf("Sum is %d\n", s);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
while由于整数下溢,循环是否包含未定义的行为?编译器是否有权假设while循环条件始终为真,因此最终会出现无限循环?
如果i是的话signed int?它不包含与阵列访问相关的陷阱吗?
更新
我运行这个和类似的代码很多次,它工作正常.此外,它是向后迭代数组和向量的流行方式.我问这个问题,以确保从标准的角度来看这种方式是可行的.
乍一看,它显然不是无限的.另一方面,有时编译器可以"优化"某些条件和代码,假设代码不包含未定义的行为.它可能导致无限循环和其他不必要的后果.看到这个.
我正在阅读着名的Undefined Behavior会导致时间旅行发布并注意到这一部分:
首先,您可能会注意到循环控件中的逐个错误.结果是函数在放弃之前读取一个超过表数组末尾的函数.经典的编译器不会特别在意.它只会生成读取越界数组元素的代码(尽管事实上这样做违反了语言规则),如果超过数组末尾的内存碰巧匹配,它将返回true .
另一方面,后经典编译器可能会执行以下分析:
通过循环的前四次,函数可能返回true.
当我是4时,代码执行未定义的行为.由于未定义的行为让我可以做任何我想做的事情,我可以完全忽略这种情况并继续假设我从来没有4.(如果假设被违反,那么会发生一些不可预测的事情,但这没关系,因为未定义的行为授予我许可无法预测.)
根据这篇文章,(较新的)编译器已经可以在编译时对未定义的行为起作用,这意味着它在某些情况下完全能够发现未定义的行为.通过消除UB代码或仅仅改变它来让恶魔飞出你的鼻子或产生龙,而不是让它为什么不允许编译器发出警告,这可能不是故意的?