我们可以访问不存在的类类型对象的成员吗?

Oli*_*liv 12 c++ strict-aliasing language-lawyer class-members

在c ++标准中,在[basic.lval] /11.6中说:

如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:[...]

  • 聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(包括递归地,子聚合或包含联合的元素或非静态数据成员),[...]

这句话是严格别名规则的一部分.

它是否允许我们通过类成员访问进行别名?

class A{ //"casted to" aggregate
  int i;
  float g;
  };

int j=10;
int l = reinterpret_cast<A*>(&j)->i;
Run Code Online (Sandbox Code Playgroud)

根据标准,只有在对象受到左值到右值转换 [conv.lval]/2的情况下才能访问对象值.

[expr.ref]没有规定object-expression必须引用该类型的对象,只是glvalue必须具有类类型(object-expression是点"."左侧的表达式).然而,有一句话反复出现在与成员访问相关的句子中,这可能意味着对我忽略的程序的限制.例如[expr.ref] /4.1:

如果E2是静态数据成员且E2的类型是T,则E1.E2是左值; 表达式指定类的命名成员.

"指定"是否意味着该成员在其生命周期内并且我不能使用类成员访问来进行伪造别名?或者[basic.lval] /11.6允许它?

xsk*_*xzr 1

对于非静态数据成员,这个词是:

\n\n
\n

如果E2是非静态数据成员,E1的类型为\xe2\x80\x9ccq1 vq1 X\xe2\x80\x9d,E2的类型为\xe2\x80\x9ccq2 vq2 T\xe2\x80\x9d ,表达式指定第一个表达式指定的对象的命名成员。

\n
\n\n

显然,由 指定的对象*reinterpret_cast<A*>(&j),即j,没有成员,因此省略未定义该行为。

\n