获取未初始化对象成员的地址是否定义明确?
Is taking the address of a member of an uninitialized object well defined?
考虑以下示例。当构造 bar
时,它为基类型 (foo
) 构造函数提供 my_member.y
的地址,其中 my_member
是尚未初始化的数据成员。
struct foo {
foo(int * p_x) : x(p_x) {}
int * x;
};
struct member {
member(int p_y) : y(p_y) {}
int y;
};
struct bar : foo
{
bar() : foo(&my_member.y), my_member(42) {}
member my_member;
};
#include <iostream>
int main()
{
bar my_bar;
std::cout << *my_bar.x;
}
这个定义好吗?获取未初始化对象的数据成员的地址是否合法?我在未初始化的对象上找到 this question about passing a reference to an uninitialized object but it's not quite the same thing. In this case, I'm using the member access operator .
。
确实不应通过初始化更改对象数据成员的地址,但这并不一定会使 采用 该地址定义良好。此外,member access operators 上的 ccpreference.com 页面是这样说的:
The first operand of both operators is evaluated even if it is not necessary (e.g. when the second operand names a static member).
我理解这意味着在 &my_member.y
的情况下 my_member
会被评估,我认为这很好(比如 int x; x;
似乎很好)但我找不到文档来支持它。
是的,您可以将 &my_member.y
传递给 foo
的构造函数,甚至可以复制指针 - 您可以使用 x(p_x)
.
解引用 指针在 foo
的构造函数中的行为未定义。 (但你不会那样做。)
首先让我们把问题准确化。
您正在做的不是使用未初始化的对象,您使用的是不在其生命周期内的对象。 my_member
是在 foo
之后构造的,因此 my_member
的生命周期还没有在 foo(&my_member.y)
开始。
before the lifetime of an object has started but after the storage which the object will occupy has been allocated [...], any glvalue that refers to the original object may be used but only in limited ways. [...] such a glvalue refers to allocated storage, and using the properties of the glvalue that do not depend on its value is well-defined. The program has undefined behavior if:
- the glvalue is used to access the object, or [...]
这里访问它的意思是具体读取或修改对象的值。
my_member
的计算产生了一个左值,并且不需要转换为纯右值,因此它仍然是一个左值。同样,my_member.y
的求值也是一个左值。然后我们得出结论,没有对象的值被访问,这是明确定义的。
考虑以下示例。当构造 bar
时,它为基类型 (foo
) 构造函数提供 my_member.y
的地址,其中 my_member
是尚未初始化的数据成员。
struct foo {
foo(int * p_x) : x(p_x) {}
int * x;
};
struct member {
member(int p_y) : y(p_y) {}
int y;
};
struct bar : foo
{
bar() : foo(&my_member.y), my_member(42) {}
member my_member;
};
#include <iostream>
int main()
{
bar my_bar;
std::cout << *my_bar.x;
}
这个定义好吗?获取未初始化对象的数据成员的地址是否合法?我在未初始化的对象上找到 this question about passing a reference to an uninitialized object but it's not quite the same thing. In this case, I'm using the member access operator .
。
确实不应通过初始化更改对象数据成员的地址,但这并不一定会使 采用 该地址定义良好。此外,member access operators 上的 ccpreference.com 页面是这样说的:
The first operand of both operators is evaluated even if it is not necessary (e.g. when the second operand names a static member).
我理解这意味着在 &my_member.y
的情况下 my_member
会被评估,我认为这很好(比如 int x; x;
似乎很好)但我找不到文档来支持它。
是的,您可以将 &my_member.y
传递给 foo
的构造函数,甚至可以复制指针 - 您可以使用 x(p_x)
.
解引用 指针在 foo
的构造函数中的行为未定义。 (但你不会那样做。)
首先让我们把问题准确化。
您正在做的不是使用未初始化的对象,您使用的是不在其生命周期内的对象。 my_member
是在 foo
之后构造的,因此 my_member
的生命周期还没有在 foo(&my_member.y)
开始。
before the lifetime of an object has started but after the storage which the object will occupy has been allocated [...], any glvalue that refers to the original object may be used but only in limited ways. [...] such a glvalue refers to allocated storage, and using the properties of the glvalue that do not depend on its value is well-defined. The program has undefined behavior if:
- the glvalue is used to access the object, or [...]
这里访问它的意思是具体读取或修改对象的值。
my_member
的计算产生了一个左值,并且不需要转换为纯右值,因此它仍然是一个左值。同样,my_member.y
的求值也是一个左值。然后我们得出结论,没有对象的值被访问,这是明确定义的。