标准中哪里说 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,这是可以的。因此,我希望上面的代码片段也不会编译。
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()
的调用实际上被编译器忽略了。
考虑以下片段:
#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,这是可以的。因此,我希望上面的代码片段也不会编译。
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()
的调用实际上被编译器忽略了。