c++ - 这是未定义的行为还是 struct init 的错误?

标签 c++ struct language-lawyer object-lifetime list-initialization

请考虑这段代码:

#include <iostream>

int main()
{
    struct A 
    { 
        int x; 
        int y; 
        int z; 

        int foo()
        {
            std::cout << "enter foo: " << this->x << "," << this->y << "," << this->z << std::endl;
            return 5;
        }       

        int moo() 
        { 
            std::cout << "enter moo: " << this->x << "," << this->y << "," << this->z << std::endl;
            this->x = 1;
            this->z = 10;
            return 2; 
        }
    };

    A b { b.foo(), b.z = b.moo(), 3};

    std::cout << "final: " << b.x << "," << b.y << "," << b.z << std::endl;

    return 0;
}

我的 VS2017(x64 版本)中的结果:

enter foo: 0,0,0
enter moo: 5,0,0
final: 1,2,3

ideone.com (gcc 6.3) 的结果 https://ideone.com/OGqvjW ):

enter foo: 0,0,3
enter moo: 5,0,3
final: 1,2,2

一个编译器立即将 z 成员设置为 3,在一切之前,然后在调用方法和赋值时覆盖它,另一个在最后,在一切之后进行。

问。对这种行为的解释是什么?

谢谢。

最佳答案

是的,这是未定义的行为:

int foo()
{
    std::cout << "enter foo: " << this->x << "," << this->y << "," << this->z << std::endl;
    //                            ~~~~~~~           ~~~~~~~           ~~~~~~~
}       

在调用foo() 时,xyz 尚未被调用尚未初始化。来自 [dcl.init]/12 :

If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced ([expr.ass]). [...] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases: [...]

其余情况均不适用。因此打印 xyz 存在未定义的行为。与只是:

int x;
std::cout << x; // ub

我之前的回答是肯定的,但出于终生原因。它建议 A b{ b.foo(), b.z = b.moo(), 3}; 中的初始化是非空的,因此 的任何成员的任何访问>b 初始化结束前为UB。然而,xskxzr 已经向我指出,为了使初始化成为非空的,你 must have constructors invoked , 而 int 没有构造函数。这使得 b 的初始化变得空洞。这在我看来在概念上很奇怪,但是这方面的措辞很清楚。

关于c++ - 这是未定义的行为还是 struct init 的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48035195/

相关文章:

c++ - 迭代多个标准列表并在它们之间移动对象

c++ - 通过键值的查找函数在 map 中搜索不正确

c++ - std::vector::push_back 是否有前置条件?

c++ - 模板参数推导 : which compiler is right here?

c++ - 响应式地检查两个队列而不 Hook CPU

c++ - 在根窗口的背景中显示彩色 X 窗口像素图

c# - 当结构仅在运行时已知时,将结构从 C++ 传递到 C#

css - 在CSS Flexbox中,为什么没有“justify-items”和“justify-self”属性?

c++ - 如何使用dlang读取二进制文件数据

C 从分配动态内存的结构中删除一条记录