c++ - 获取未初始化对象成员的地址是否定义明确?

标签 c++ language-lawyer object-lifetime ctor-initializer member-access

考虑以下示例。当 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关于传递对未初始化对象的引用,但这并不完全相同。在这种情况下,我使用的是 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 是在 foo 之后构造的,因此 my_member 的生命周期还没有从 foo(&my_member.y) 开始.

来自 [basic.life]

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 的评估也是一个左值。然后我们得出结论,没有对象的值被访问过,这是明确定义的。

关于c++ - 获取未初始化对象成员的地址是否定义明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54206796/

相关文章:

c++ - 无法使简单的 flex 示例正常工作

c++ - 用返回空 vector 的对象填充 vector

c++ - 在 C++ 中创建静态全局变量时

c++ - 延长临时对象的生命周期而不复制它

c++ - 当函数返回 CString 时会发生什么?

c++ - 指向虚函数的指针

派生列表中的 C++ 作用域运算符

java - 为什么类不能扩展其中出现的静态嵌套类?

c++ - 常量表达式中引用类型的变量

c++ - bcc32 和 bcc32c 对象生命周期的区别