相关疑难解决方法(0)

24
推荐指数
2
解决办法
3000
查看次数

while(i - )s + = a [i]; 在C和C++中包含未定义的行为?

考虑简单的代码:

#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?它不包含与阵列访问相关的陷阱吗?

更新

我运行这个和类似的代码很多次,它工作正常.此外,它是向后迭代数组和向量的流行方式.我问这个问题,以确保从标准的角度来看这种方式是可行的.

乍一看,它显然不是无限的.另一方面,有时编译器可以"优化"某些条件和代码,假设代码不包含未定义的行为.它可能导致无限循环和其他不必要的后果.看到这个.

c c++ undefined-behavior

6
推荐指数
2
解决办法
381
查看次数

如果可能存在未定义的行为,为什么编译器不会警告您?

我正在阅读着名的Undefined Behavior会导致时间旅行发布并注意到这一部分:

首先,您可能会注意到循环控件中的逐个错误.结果是函数在放弃之前读取一个超过表数组末尾的函数.经典的编译器不会特别在意.它只会生成读取越界数组元素的代码(尽管事实上这样做违反了语言规则),如果超过数组末尾的内存碰巧匹配,它将返回true .

另一方面,后经典编译器可能会执行以下分析:

通过循环的前四次,函数可能返回true.

当我是4时,代码执行未定义的行为.由于未定义的行为让我可以做任何我想做的事情,我可以完全忽略这种情况并继续假设我从来没有4.(如果假设被违反,那么会发生一些不可预测的事情,但这没关系,因为未定义的行为授予我许可无法预测.)

根据这篇文章,(较新的)编译器已经可以在编译时对未定义的行为起作用,这意味着它在某些情况下完全能够发现未定义的行为.通过消除UB代码或仅仅改变它来让恶魔飞出你的鼻子或产生龙,而不是让它为什么不允许编译器发出警告,这可能不是故意的?

c++ undefined-behavior

4
推荐指数
1
解决办法
511
查看次数

标签 统计

undefined-behavior ×3

c ×2

c++ ×2

infinite-loop ×1