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

Som*_*ken 4 c++ undefined-behavior

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

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

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

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

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

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

Moh*_*ain 5

编译器的工作是将代码从高级语言编译到较低级别.如果您收到描述性错误或警告消息,那么现在是时候感谢编译器为您做了额外的工作.要获得所需的警告,请使用一些静态代码分析工具.

规范中没有明确定义的任何内容都是未定义的,并且不可能准备一个未定义行为的综合列表.对所有此类行为发出警告可能是不可能的.

实际上,在许多情况下,编译器会对未定义的行为发出警告,特别是-W -Wall -Wextra -O2在gcc上使用正确的警告标志.(使用像-O2编译器这样的优化标志会对代码进行回归分析并产生更多警告)