这个问题是对以下问题的跟进:当它实际上并不指向 char 数组时,是否添加到“char *”指针 UB?
在CWG 1314中,CWG 确认使用指针在标准布局对象内执行指针运算是合法的unsigned char
。这似乎意味着类似于链接问题中的一些代码应该按预期工作:
struct Foo {
float x, y, z;
};
Foo f;
unsigned char *p = reinterpret_cast<unsigned char*>(&f) + offsetof(Foo, z); // (*)
*reinterpret_cast<float*>(p) = 42.0f;
(为了更清楚,我已替换char
为。)unsigned char
但是,似乎 C++17 中的新更改意味着该代码现在是 UB,除非std::launder
在两个reinterpret_cast
s. reinterpret_cast
两个指针类型之间的 a 的结果等价于两个static_cast
s:第一个指向cv void*
,第二个指向目标指针类型。但是 [expr.static.cast]/13 暗示这会产生一个指向原始对象的指针,而不是指向目标类型对象的指针,因为类型Foo
的对象在其第一个字节处不能与对象进行指针互转换unsigned char
,也不是指针unsigned char
的第一个字节处的对象与自身可相互转换。f.z
f.z
我很难相信委员会打算做出改变来打破这个非常常见的习惯用法,使所有 C++17 之前的使用都offsetof
未定义。