标准中哪里说 U::j 的默认成员初始值设定项应该被编译器忽略?

Where in the Standard does it say that the default member initializer for U::j should be ignored by the compiler?

考虑以下片段:

#include <iostream>
union U{
    U(): i(1) {}
    int i;
    int j = 2;    // this default member initializer is ignored by the compiler
};

U u;

int main(){
    std::cout << u.i << '\n';
    std::cout << u.j << '\n';
}

代码打印(见live example):

1
1

标准中哪里说成员 U::j 的默认成员初始值设定项被编译器忽略?

请注意,下面的联合不会编译,根据 [class.union.anon]/4,这是可以的。因此,我希望上面的代码片段也不会编译。

live example:

union U{
    int i = 1;
    int j = 2;
};

Where in the Standard does it say that the default member initializer for the member U::j is ignored by the compiler?

请参阅 C++17 CD 中的 [class.base.init] 第 9 段项目符号 9.1。

N.B。你的演示有未定义的行为,因为工会的活跃成员是 i 但你从 j 读取。这适用于某些编译器作为非标准扩展,但在 ISO C++ 中是不允许的。

请注意,您正在声明一个联合对象,其中所有成员共享同一内存区域 - 成员变量变成相同数据的不同"typed views"。

因此,由于成员 i 和 j 有效地存储在相同的内存位置,您对 j 执行的任何初始化(使用初始化器)都将被构造函数设置 i 覆盖。

只是为了测试,从构造函数中删除 i 的初始化:

#include <iostream>
union U{
    U() {}
    int i;
    int j = 2;    // this initializes both i & j
};

U u;

int main(){
    std::cout << u.i << '\n';
    std::cout << u.j << '\n';   
}

输出将是

2
2

更新: 根据@Ayrosa 的评论和好奇,我修改了原始代码片段以使用函数(而不是常量)执行一些初始化以引起副作用。

#include <iostream>

int static someStatic()
{
    std::cout << "Initializer was not ignored\n";
    return(2);
}

union U{
    U(): i(1) {}
    int i;
    int j = someStatic();    // this default member initializer is ignored by the compiler
};

U u;

int main(){
    std::cout << u.i << '\n';
    std::cout << u.j << '\n';
}

结果是:

1
1

意味着对 someStatic() 的调用实际上被编译器忽略了。