GCC - 没有关于带有 -O0 的未初始化数组的警告

2024-04-03

我的 GCC 7.3.0 和 8.2.0 有一些我无法解释的奇怪行为。 这个程序显然以分段错误结束:

int main()
{
    double array[2]={0, 0};
    printf("%f\n", array[999]);

    return 0;
}

编译为

gcc -Wall -O2 main.c

产生警告

main.c: In function 'main':
main.c:6:5: warning: 'array[999]' is used uninitialized in this function [-Wuninitialized]
     printf("%f\n", array[999]);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~

但关闭优化后:

gcc -Wall main.c

它根本不产生任何警告。 我的代码 linter 和调试编译 (gcc -g) 使用 -O0 并且没有发现我犯的类似越界错误,直到我将其编译为打开优化的发布。在 linter 中设置 -O1 按预期发布警告。


这是 GCC 中长期存在的、有记录的限制。引用GCC 3.0 手册 https://gcc.gnu.org/onlinedocs/gcc-3.0.4/gcc_3.html#IDX165:

-Wuninitialized

如果在未初始化的情况下使用自动变量,或者变量可能被变量破坏,则发出警告setjmp call.

这些警告仅在优化编译时才可能出现,因为它们需要仅在优化时计算的数据流信息。如果你不指定-O,您根本不会收到这些警告。

The 当前版本的手册 https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Warning-Options.html#index-Wuninitialized实际上删除了该引用的第二段,而是说“因为这些警告取决于优化,因此存在警告的确切变量或元素取决于精确的优化选项和所使用的 GCC 版本。”这是因为,在 GCC 3.0(2001 年发布)和 GCC 8.2(2018 年发布)之间的某个时刻,编译器得到了改进,因此will在不优化时至少对未初始化变量的某些使用发出警告。例如,简单的测试

int foo(void) { int x; return x; }

当使用 GCC 8.2 进行编译时,确实会引发警告-O0 -Wall.

值得指出的是perfect未初始化变量的诊断简化为臭名昭著的停机问题 https://en.wikipedia.org/wiki/Halting_problem——这意味着这是不可能完成的。您可以实现一组保守正确的规则(它们将检测未初始化变量的所有使用,但它们可能会声称某些变量在未初始化的情况下使用),例如爪哇的明确的分配 https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html规则,但这种方法历来在 C 程序员中并不受欢迎。考虑到在不优化时需要最少的误报以及快速编译的需求,GCC 在优化时进行更详细分析的方法是可以理解的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GCC - 没有关于带有 -O0 的未初始化数组的警告 的相关文章

  • gcc 和 ld 中与位置无关的可执行文件的 -fPIE 选项是什么?

    它将如何更改代码 例如函数调用 PIE是支持地址空间布局随机化 ASLR http en wikipedia org wiki Address space layout randomization在可执行文件中 在创建PIE模式之前 程序的
  • 非模板函数中的尾随返回类型[重复]

    这个问题在这里已经有答案了 我见过有人使用以下语法来实现函数 auto get next gt int 代替 int get next 我理解两者 并且我知道尾随返回类型语法对于使用 decltype 的模板代码很有用 就我个人而言 我会避
  • 无法在 CUDA 中找到 1 到 100 数字的简单和?

    我正在研究使用 CUDA 的图像处理算法 在我的算法中 我想使用 CUDA 内核找到图像所有像素的总和 所以我在cuda中制作了内核方法 来测量16位灰度图像的所有像素的总和 但我得到了错误的答案 所以我在cuda中编写了一个简单的程序来查
  • 来自 double 的 static_cast 可以优化分配给 double 吗?

    我偶然发现了一个我认为不必要的功能 并且通常让我感到害怕 float coerceToFloat double x volatile float y static cast
  • C++中类成员函数相互调用有什么好处?

    我是 C 新手 我发现下面的编程风格对我来说很有趣 我在这里写了一个简化版本 include
  • 每个元素的 asp.net Web 表单自定义错误消息

    我创建了一个 Web 应用程序 表单 以及后端 SQL 插入和查询 目前我正在显示所有用户错误消息 div style padding 1em div
  • 获取列表框中视图中的项目

    我有一个 ListBox 其属性 VirtualizingStackPanel VirtualizationMode 设置为 回收 我正在绑定一个自定义集合 实现IList and IList
  • 公交车公共交通算法

    我正在开发一个可以查找公交路线的离线 C 应用程序 我可以提取时间表 巴士 路线数据 我正在寻找适用于基本数据的最简单的解决方案 可以使用什么算法来查找从巴士站 A 到巴士站 B 的路线 是否有适用于 C Java 的开源解决方案 数据库的
  • 重载算术运算符

    赋值运算符可以声明为 T 运算符 const t 在类中 但不能以这种方式定义算术运算符 它必须是友元函数 我不明白为什么 你能解释一下吗 算术运算符不必须是友元 那么你可以这样定义 MyClass MyClass operator con
  • 从图像创建半透明光标

    是否可以从图像创建光标并使其半透明 我目前正在拍摄自定义图像并覆盖鼠标光标图像 如果我可以将其设为半透明 那就太好了 但不是必需的 销售人员喜欢闪亮的 目前正在做这样的事情 Image cursorImage customImage Get
  • X 轴和 Z 轴上的 Quaternion.Slerp,无 Y 轴

    I am trying to rotate the Player about X Y and Z axis The Y axis should not move from last angle Example if I rotate 45
  • DateTime.ParseExact - 为什么 yy 变成 2015 而不是 1915

    为什么 NET 假定以下年份是 2015 年 而不是 1915 年 var d DateTime ParseExact 20 11 15 dd MM yy new CultureInfo en GB 我想 它会尝试接近 但其背后是否有合理的
  • 如何在 C++ 中正确使用 cin.fail()

    我正在编写一个程序 从用户那里获取整数输入cin gt gt iUserSel 如果用户输入一个字母 程序就会进入无限循环 我试图用下面的代码来阻止这种情况 但程序进入无限循环并打印出 错误 输入 我该如何修复我的程序 cin gt gt
  • 当我尝试传递临时地址作为参数时,它是一个 UB 吗?

    对于以下 C 代码 include
  • 让 Windows 尝试读取文件

    我正在对 Windows 文件系统进行某种封装 当用户请求打开文件时 Windows 调用我的驱动程序来提供数据 在正常操作中 驱动程序返回缓存的文件内容 但是 在某些情况下 实际文件没有缓存 我需要从网络下载它 问题是是否有可能让 Win
  • 查找数组中的多个索引

    假设我有一个像这样的数组 string fruits watermelon apple apple kiwi pear banana 是否有一个内置函数可以让我查询 apple 的所有索引 例如 fruits FindAllIndex ap
  • 为什么存在系统调用

    我一直在阅读有关系统调用及其在 Linux 中如何工作的内容 我还有更多的阅读要做 但我读过的一件事都没有回答 那就是 为什么我们需要系统调用 我知道系统调用是用户空间程序要求内核执行某些操作的请求 但我的问题基本上是 为什么用户空间程序本
  • 尝试后终于没有被调用

    由于某种原因 在我的控制台应用程序中 我无法运行我的finally 块 我编写这段代码是为了测试finally块是如何工作的 所以它非常简单 static void Main int i 0 try int j 1 i Generate a
  • java有类似C#的属性吗? [复制]

    这个问题在这里已经有答案了 C 属性 我的意思是 get 和 set 方法 是一个非常有用的功能 java 也有类似 C 的属性吗 我的意思是我们如何在 java 中实现类似以下 C 代码的内容 public string Name get
  • 如何使用 Microsoft Graph API 更新 MailboxSettings

    我想从不同的日历更新邮箱设置 如何构建可以通过 Microsoft Graph 更新 MailboxSetting 的请求 这是我的代码示例 但有例外 代码示例 User obj GraphServiceClient Users roomC

随机推荐