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

Kil*_*Kid 4 c++ struct object-lifetime language-lawyer 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;
}
Run Code Online (Sandbox Code Playgroud)

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

enter foo: 0,0,0
enter moo: 5,0,0
final: 1,2,3
Run Code Online (Sandbox Code Playgroud)

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

enter foo: 0,0,3
enter moo: 5,0,3
final: 1,2,2
Run Code Online (Sandbox Code Playgroud)

一个编译器z在所有内容之前立即将成员设置为3,然后在调用方法和赋值时将其覆盖,另一个在最后,在所有内容之后执行.

问:这种行为会有什么解释?

谢谢.

Bar*_*rry 7

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

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

在该点foo()被调用,x,y,和z尚未初始化.来自[dcl.init]/12:

如果没有为对象指定初始化程序,则默认初始化该对象.当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定的值,并且如果没有对该对象执行初始化,则该对象保留不确定的值,直到该值被替换([expr.ass]).[...]如果评估产生不确定的价值,则行为是不确定的,除非在下列情况下:[...]

其余案件均不适用.所以打印x,y并且z存在未定义的行为.与以下完全不同:

int x;
std::cout << x; // ub
Run Code Online (Sandbox Code Playgroud)

我之前的回答是肯定的,但是出于终生的原因.它建议初始化A b{ b.foo(), b.z = b.moo(), 3};是非空的,因此b在初始化结束之前任何成员的任何访问都是UB.但是,xskxzr后来告诉我,为了使初始化非空,你必须调用构造函数,并且int没有构造函数.这使得初始化为b空.这在概念上对我来说很奇怪,但这方面的措辞很清楚.