reinterpret_cast 从对象到第一个成员

我正在查看此 answer,我想知道是否使用 reinterpret_cast 将对象投射到其第一个成员并使用结果在 C++ 中可能是安全的.

I was looking at this answer and I was wondering if casting an object to its first member with reinterpret_cast and using the result could be safe in C++.

假设我们有一个类 A、一个类 B 和一个 B 的实例 b:

Let's assume that we have a class A, a class B and an instance b of B:

class A{
public:
    int i;
    void foo(){}
};

class B{
public:
    A a;
};

B b;

问题 1:这样使用 ba 是否安全:reinterpret_cast<A*>(&b)->foo()?

Question 1: Is it safe to use b.a like this: reinterpret_cast<A*>(&b)->foo()?

注意:一般情况下,我们假设类及其成员都是标准布局.

Note: In the general case we suppose that the class and its member are both standard layout.

我在 reinterpret_cast 上的可用参考资料的讲座告诉我这种用法应该被授权,因为没有别名违规,但是它与许多答案相冲突,例如 this one.

My lecture of the available references on reinterpret_cast tells me such usage should be authorized as there is no aliasing violation, however it conflicts with many answers like this one.

问题2:这样使用ba是否安全:static_cast<A*>(static_cast<void*>(&b))->foo()?

Question2: Is it safe to use b.a like this: static_cast<A*>(static_cast<void*>(&b))->foo()?

推荐答案

是的,因为这里的两个类都是标准-布局类型,您可以在&b&ba之间进行转换.

Yes, because both classes here are standard-layout types, you can convert between &b and &b.a.

reinterpret_cast<A*>(p) 被定义为与 static_cast<A*>(static_cast<void*>(p)) 相同, (5.2.10p7) 所以你的两个问题是等价的.

reinterpret_cast<A*>(p) is defined to be the same as static_cast<A*>(static_cast<void*>(p)), (5.2.10p7) so both your questions are equivalent.

对于标准布局类,结构/类的地址与其第一个非静态成员 (9.2p19) 的地址相同.并且 static_cast to/from void* 将保留地址 (5.2.9p13),这意味着结果将是有效的.

For standard-layout classes, the address of the struct/class is the same as the address of its first non-static member (9.2p19). And static_cast to/from void* will preserve the address (5.2.9p13), meaning the result will be valid.

如果类不是标准布局,则不能依赖此行为.

If the classes were not standard-layout, you could not rely on this behavior.

相关文章