c - GCC:未定义的溢出行为是否应该保持逻辑一致性?
问题描述
以下代码在我的系统上产生了奇怪的东西:
#include <stdio.h>
void f (int x) {
int y = x + x;
int v = !y;
if (x == (1 << 31))
printf ("y: %d, !y: %d\n", y, !y);
}
int main () {
f (1 << 31);
return 0;
}
编译后-O1
,打印出来y: 0, !y: 0
。
int v
现在,除了删除or行会产生预期结果这一令人费解的事实之外if
,我对未定义的溢出行为转化为逻辑不一致感到不舒服。
这应该被认为是一个错误,还是 GCC 团队的理念,即一个意外行为可能会级联成逻辑矛盾?
解决方案
当调用未定义的行为时,任何事情都可能发生。毕竟,它被称为未定义行为是有原因的。
这应该被认为是一个错误,还是 GCC 团队的理念,即一个意外行为可能会级联成逻辑矛盾?
这不是一个错误。我对 GCC 团队的理念了解不多,但总的来说,未定义的行为对于编译器开发人员实现某些优化是“有用的”:假设某些事情永远不会发生,这样优化代码就更容易了。UB之后什么事情都可能发生的原因正是因为这个。编译器做了很多假设,如果其中任何一个被破坏,那么发出的代码就不能被信任。
正如我在另一个答案中所说:
未定义的行为意味着任何事情都可能发生。没有解释为什么在调用未定义的行为后会发生任何奇怪的事情,也不需要. 编译器可以很好地发出 16 位实模式 x86 程序集,产生删除整个主文件夹的二进制文件,发出 Apollo 11 Guidance Computer 程序集代码,或其他任何东西。这不是一个错误。它完全符合标准。
推荐阅读
- asp.net - 没有“IEnumerable”类型的 ViewData 项
' 有键 'ddlcontent' - android - 使用 Kotlin,您可以将 Google 存储 URL (GS://) 转换为 HTTPS 吗?
- javascript - 延迟函数返回,直到设置值
- django - 通过 ubuntu 服务器远程使用我的 django
- javascript - 有没有办法使用 mapbox draw 将图像添加到多边形的每个点?
- c# - Task.WhenAny 之后的任务取消
- arrays - [SwiftUI]:ForEach 不适用于字典数组、带数组的字典
- javascript - 如何在 npm 中阻止广告?
- ionic4 - 如何为视频创建保留,使用相机或其他插件在 Ionic 4/5 中点击类似 whatsapp 功能的照片
- angular - 如何在远程 Tomcat 服务器中渲染 Angular Universal