class个成员变量的初始化顺序
Order of initialization of class member variables
考虑以下代码片段:
class A
{
public:
A(int a, int b) : j(a), i(j + b) {}
int i, j;
};
int main()
{
A a(10, 20);
std::cout << a.i << " " << a.j << std::endl;
return 0;
}
标准says成员变量的初始化顺序就是声明的顺序。在这种情况下,i
将在 j
之前被初始化。由于 j
尚未初始化,i = *a garbage value* + 20
,然后 j
用 10
.
初始化
密码prints20 10
.
即j
在计算i
时被认为是0
。
标准是否保证在这种情况下使用内置类型的默认值?还是只是垃圾值恰好是0
?还是 未定义的行为?
j + b
是未定义的行为,因为它在允许这样做的特定实例之一之外使用不确定值(j
在初始化之前的值)(所有这些都与char
变体和 std::byte
,而不是 int
,不确定值)。
在 C++20 中,它也会有未定义的行为,因为您在其生命周期之外访问 j
。据我所知,在 C++17 中 j
的生命周期开始于其存储分配之前,因为 j
的初始化是 vacuous。不过,C++20 中空初始化和生命周期的定义发生了变化。
所以在任何情况下,在变量初始化之前使用它都是非常不明智的。
Does the standard guarantee to use default values for built-in types in such a scenario?
没有。在这种情况下,该值是不确定的。
Or is it undefined behavior?
是的。读取不确定值的行为未定义(窄字符类型 IIRC 除外)。
考虑以下代码片段:
class A
{
public:
A(int a, int b) : j(a), i(j + b) {}
int i, j;
};
int main()
{
A a(10, 20);
std::cout << a.i << " " << a.j << std::endl;
return 0;
}
标准says成员变量的初始化顺序就是声明的顺序。在这种情况下,i
将在 j
之前被初始化。由于 j
尚未初始化,i = *a garbage value* + 20
,然后 j
用 10
.
密码prints20 10
.
即j
在计算i
时被认为是0
。
标准是否保证在这种情况下使用内置类型的默认值?还是只是垃圾值恰好是0
?还是 未定义的行为?
j + b
是未定义的行为,因为它在允许这样做的特定实例之一之外使用不确定值(j
在初始化之前的值)(所有这些都与char
变体和 std::byte
,而不是 int
,不确定值)。
在 C++20 中,它也会有未定义的行为,因为您在其生命周期之外访问 j
。据我所知,在 C++17 中 j
的生命周期开始于其存储分配之前,因为 j
的初始化是 vacuous。不过,C++20 中空初始化和生命周期的定义发生了变化。
所以在任何情况下,在变量初始化之前使用它都是非常不明智的。
Does the standard guarantee to use default values for built-in types in such a scenario?
没有。在这种情况下,该值是不确定的。
Or is it undefined behavior?
是的。读取不确定值的行为未定义(窄字符类型 IIRC 除外)。