【发布时间】:2019-01-31 17:40:22
【问题描述】:
更具体地说,假设A 是B 的可访问基类,那么以下代码是否会产生未定义的行为,并且根据标准是否保证不会触发断言?
void test(B b1, B b2) {
A* a2 = &b2;
auto offset = reinterpret_cast<char*>(a2) - reinterpret_cast<char*>(&b2);
A* a1 = reinterpret_cast<A*>(reinterpret_cast<char*>(&b1) + offset);
assert(a1 == static_cast<A*>(&b1));
}
编辑:
我知道所有常见的编译器供应商都以与test 的隐含假设兼容的方式实现 C++ 对象布局(即使考虑到虚拟继承)。我正在寻找的是标准中这种行为的保证(隐式或显式)。或者,也可以接受标准提供的对象存储布局保证范围的合理详细描述,作为不保证这种行为的证据。
【问题讨论】:
-
如果涉及虚拟继承,它可能不起作用。此外,所有这些强制转换都可能通过违反严格的别名规则在某处表现出未定义的行为,但我懒得追究。
-
如果
A是虚拟基地 - 否。 -
如果标准对上述内容提供任何保证,我会感到惊讶。所以它可能有效,但它属于“未指定行为”
-
我认为这仅适用于标准布局类型。对于其他类型,标准没有强加任何此类要求,因此允许实现做“疯狂”的事情。并不是说我知道
assert会失败的任何实现(对于任何类型,即使是虚拟继承)。 -
缺少标签
language-lawyer
标签: c++ language-lawyer reinterpret-cast object-layout