严格别名是否会阻止您通过其他类型写入char数组?

zne*_*eak 1 c++ strict-aliasing language-lawyer

我的理解是在Basic.lval 11中定义了C++中的严格别名:

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

  • (11.1)对象的动态类型,
  • (11.2)对象的动态类型的cv限定版本,
  • (11.3)与对象的动态类型类似的类型(在conv.qual中定义),
  • (11.4)与对象的动态类型对应的有符号或无符号类型的类型,
  • (11.5)一种类型,它是有符号或无符号类型,对应于对象动态类型的cv限定版本,
  • (11.6)聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(递归地,包括子聚合或包含联合的元素或非静态数据成员),
  • (11.7)一种类型,它是对象的动态类型的(可能是cv限定的)基类类型,
  • (11.8)一个char,unsigned char或std?::?byte类型.

通过我的阅读,每11.8,这总是合法的,因为程序x通过类型的glvalue 访问存储的值unsigned char:

int x = 0xdeadbeef;
auto y = reinterpret_cast<unsigned char*>(&x);
std::cout << y[1];
Run Code Online (Sandbox Code Playgroud)

我很好奇使用指向别名的指针unsigned char:

alignas(int) unsigned char[4] x;
auto y = reinterpret_cast<int*>(x);
*y = 0xdeadbeef;
Run Code Online (Sandbox Code Playgroud)

这是违反严格别名的吗?我的阅读是它不是,但我只是在另一个线程上被告知它是.仅对于basic.lval,在我看来没有UB,因为程序不会尝试访问存储的值:它存储一个新的而不读取它,只要后续读取使用x,就不会发生违规.

小智 5

关于"访问"的定义:

http://eel.is/c++draft/defns.access

3.1 access [defns.access]
⟨execution-time动作⟩读取或修改对象的值

换句话说,存储值也是"访问".它仍然是UB.