【问题标题】:Can g++ fill uninitialized POD variables with known values?g ++可以用已知值填充未初始化的POD变量吗?
【发布时间】:2010-04-16 14:15:05
【问题描述】:

我知道调试选项下的 Visual Studio 将使用已知值填充内存。 g++(任何版本,但 gcc 4.1.2 最有趣)是否有任何选项可以 用可识别的值填充未初始化的本地 POD 结构?

struct something{ int a; int b; };
void foo() {
    something uninitialized;
    bar(uninitialized.b);
}

我希望uninitialized.b 是不可预测的随机性;显然是一个错误并且很容易 发现优化和警告是否打开。但是只用 -g 编译,没有 警告。一位同事有一个案例,其中与此类似的代码有效,因为它 巧合地有一个有效值;当编译器升级时,它开始失败。 他认为这是因为新编译器将已知值插入到结构中 (很像 VS 填充 0xCC 的方式)。根据我自己的经验,它只是不同 碰巧无效的随机值。

但现在我很好奇 - 是否有任何 g++ 设置可以让它填充 否则标准会说应该未初始化的内存?

【问题讨论】:

    标签: c++ g++


    【解决方案1】:

    任何 C++ 编译器都可以使用以下语法将任何 POD 类型初始化为其“零”值:

    int i = int();
    float f = float();
    MyStruct mys = MyStruct();
    // and generally:
    T t = T();
    

    如果您想谈论调试,那是另外一回事......

    (顺便说一句,我认为 VS 在“调试模式”下将 all 未初始化的内存初始化为 0xCC,因此无论您跳转到哪里(例如调用错误的函数指针),都不会碰巧是实际的程序代码/数据 int3 被提出。)

    【讨论】:

    • 或者,对于那些渴望让 C++ 看起来像 Lisp 的人,T t((T())) :-)
    • @James:你说的完全正确,但是这种语法让我进退两难。我不知道看着它更疼的是什么——我的眼睛还是我的心。 :)
    • 是的,它可以初始化,但它没有,所以我想我真的倾向于调试帮助。听起来解决方案在 g++ 之外,不过(valgrind et.al)。
    【解决方案2】:

    我认为 gcc/g++ 中不存在这样的选项/功能。

    例如,所有全局(和静态)变量都位于.bss 部分中,该部分始终初始化为零。但是,为了兼容性,未初始化的会放在 .bss 的特殊部分中。

    如果您也希望它们归零,您可以将-fno-common 参数传递给编译器。或者,如果您需要基于每个变量,请使用 __attribute__ ((nocommon))

    对于堆,可以编写自己的分配器来完成您所描述的。但是对于堆栈,我认为没有一个简单的解决方案。

    【讨论】:

    • 我认为该功能也不存在,但是 gcc 手册又长又深,之前隐藏在其中的内容让我感到惊讶。
    【解决方案3】:

    我不相信 g++ 会检测到所有这样的情况,但Valgrind 肯定会。

    【讨论】:

    • 是的,其他分析工具似乎是解决方案。看起来像是编译器可以安排的东西,但如果没有,也不会太令人惊讶。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 2016-02-24
    相关资源
    最近更新 更多