Bri*_*ian 26 c++ offsetof language-lawyer c++17
该问题是针对以下问题的后续措施:当它实际上未指向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;
Run Code Online (Sandbox Code Playgroud)
(为了更清楚起见,我用替换char了unsigned char。)
但是,似乎C ++ 17中的新更改意味着该代码现在是UB,除非std::launder在两个reinterpret_casts 之后都使用。reinterpret_cast两种指针类型之间的a结果等于两个static_casts:第一个为cv void*,第二个为目标指针类型。但是[expr.static.cast] / 13暗示这会生成指向原始对象的指针,而不是指向目标类型的对象的Foo指针,因为类型的对象不能与unsigned char对象的第一个字节进行指针互换,也不是一个unsigned char对象在的第一个字节f.z指针相互转换与f.z本身。
我很难相信委员会打算进行更改以打破这种非常普遍的习惯用法,从而使C ++ 17之前的所有用法都不offsetof确定。
你的问题是:
在标准布局对象中进行指针算术时(例如,使用 offsetof),我们是否需要使用 std::launder?
不。
std::launder在这种情况下不会改变任何内容,因此与所提供的示例无关(我认为编辑洗衣问题或提出另一个问题)。
std::launder通常只在某些情况下需要(例如,由于 const 成员),您以某种运行时方式(例如,通过放置 new)更改(或创建)底层对象。助记:该对象是“脏”的,需要进行“编辑”。std::launder
仅使用标准布局类型不会导致您需要使用 std::launder 的情况。