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 的未初始化数组的警告 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现

随机推荐