GCC 对未初始化数据的警告似乎与标准所说的相反

问题描述 投票:0回答:1

下面给出了详细的代码,但基本上是:我有一个类,其中包含一些未初始化的数据(未在构造函数中设置)。在某些情况下复制此类的实例时,GCC 不会发出警告,即使它正在读取未初始化的数据来执行此操作。然后,当将数据包装在

union
中时,GCC does 发出警告,但据我了解,这是标准 does 进行定义行为的一种情况。因此,在第二种情况下,它似乎应该发出警告。

换句话说,GCC 的行为似乎与应有的完全相反。

旁白:我意识到这是在处理未定义的行为,所以编译器不欠我任何东西,但鉴于GCC对这种情况有特定的警告,他们反对(我的解释)似乎很奇怪标准。

请帮助我理解正在发生的问题。

这里是演示该问题的 godbolt 实时链接:https://godbolt.org/z/Kdaa8M8qa

注意

-Wuninitialized
的使用。

1.简单的非工会案例

struct MyObj {
    MyObj()
        // leave data uninitialized
        //: val(123), fval(9.5f)
    {}

    // Note: compiler-provided copy constructor
    
    //union {
        int val;
        float fval;
    //};
};

在这里,当我们将此对象放入包含对象中,并复制该容器的实例时,我们会收到来自 GCC 的 no 警告,即使

MyObj::val
fval
显然未初始化,并复制它们因此显然是UB。我希望
-Wuninitialized
能够抓住这个明显的问题。

请参阅上面给出的 godbolt 链接,查看

Container
包装类的使用。

2.联盟案例

相同的代码,但使用了联合

struct MyObj {

    // ...
    // same as above
    // ...
    
    union {
        int val;
        float fval;
    };
};

在这里,我们与上面相同,但是将成员包装在一个联合体中。 根据我对标准的理解,工会得到特殊待遇,并且他们复制了“对象表示”(就像

memcpy
所做的那样)。因此,我们可以通过这种方式复制未初始化的值,即使它们具有陷阱表示等。

然而,令人困惑的是,通过这一更改,现在 GCC 发出了警告。

所以,我想知道:GCC 在这两种情况下的行为都是正确的,而我的理解是错误的吗?如果是这样,请详细解释原因。

c++ gcc initialization compiler-warnings member-initialization
1个回答
0
投票

错误并不是说复制分配是未初始化的使用。

例如,这没有警告:

cont = Container{ 10, {} };
cont.o.val = 2;  // <-- This is the added line
printf("Internal undefined val: %d (0x%x)\n", cont.o.val, cont.o.val);

警告应该是说

<anonymous>
(来自
Container{ 10, {} }
的临时物化)在未初始化时正在读取 ,与
printf
行中。

虽然错误应该显示类似

<temporary>.Container::o.MyObj::<anonymous>.MyObj::<unnamed union>::val
的内容并指向
printf
行,而不是创建临时文件的行(也许它应该有两个位置?)

如果您使用构造函数而不是赋值,它确实会告诉您正确的行:

Container cont = Container{ 10, {} };
// cont.o.val = 2;
printf("Internal undefined val: %d (0x%x)\n", cont.o.val, cont.o.val);
<source>:50:11: warning: 'cont.Container::o.MyObj::<anonymous>.MyObj::<unnamed union>::val' is used uninitialized in this function [-Wuninitialized]
     printf("Internal undefined val: %d (0x%x)\n", cont.o.val, cont.o.val);
     ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
© www.soinside.com 2019 - 2024. All rights reserved.