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.
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |