reinterpret_cast 从对象到第一个成员
reinterpret_cast from object to first member
我在看这个 answer,我想知道使用 reinterpret_cast 将对象强制转换为它的第一个成员并使用结果在 C++ 中是否安全。
假设我们有一个 class A、一个 class B 和一个 B 的实例 b:
class A{
public:
int i;
void foo(){}
};
class B{
public:
A a;
};
B b;
问题 1:这样使用 b.a 安全吗:reinterpret_cast<A*>(&b)->foo()
?
注意:一般情况下我们假设class及其成员都是标准布局。
我在 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:这样使用 b.a 安全吗:static_cast<A*>(static_cast<void*>(&b))->foo()
?
是的,因为这里的类都是standard-layout types,可以在&b
和&b.a
之间转换。
reinterpret_cast<A*>(p)
被定义为与 static_cast<A*>(static_cast<void*>(p))
相同,(5.2.10p7) 所以你的两个问题是等价的。
对于标准布局 类,struct/class 的地址与其第一个非静态成员 (9.2p19) 的地址相同。 static_cast
to/from void*
将保留地址 (5.2.9p13),这意味着结果将有效。
如果 类 不是标准布局,您不能依赖此行为。
正式回答:是的,有些情况下你可以这样做(见@interjay的回答)。
实际答案:请不要那样做。真的。主要是直路可用时:
b.a.foo();
换句话说,如果至少有极小的机会避免类型转换,就不要使用它们。
如果您对 C++98,2003 感兴趣:
Q1 和 Q2 是相同的结构。
您的类型是PODs。 POD在实例化过程中开头没有填充是存在保证....但在继承过程中不存在保证。所以 reinterpret_cast 是不安全的...
my question about POD layout
"In real life" 比较安全,因为大部分编译器都是在继承的时候进行内存布局的,比如http://phpcompiler.org/articles/virtualinheritance.html
但请注意 A 对象基地址 和 B 对象基地址 可能具有不同值的风险。
我在看这个 answer,我想知道使用 reinterpret_cast 将对象强制转换为它的第一个成员并使用结果在 C++ 中是否安全。
假设我们有一个 class A、一个 class B 和一个 B 的实例 b:
class A{
public:
int i;
void foo(){}
};
class B{
public:
A a;
};
B b;
问题 1:这样使用 b.a 安全吗:reinterpret_cast<A*>(&b)->foo()
?
注意:一般情况下我们假设class及其成员都是标准布局。
我在 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:这样使用 b.a 安全吗:static_cast<A*>(static_cast<void*>(&b))->foo()
?
是的,因为这里的类都是standard-layout types,可以在&b
和&b.a
之间转换。
reinterpret_cast<A*>(p)
被定义为与 static_cast<A*>(static_cast<void*>(p))
相同,(5.2.10p7) 所以你的两个问题是等价的。
对于标准布局 类,struct/class 的地址与其第一个非静态成员 (9.2p19) 的地址相同。 static_cast
to/from void*
将保留地址 (5.2.9p13),这意味着结果将有效。
如果 类 不是标准布局,您不能依赖此行为。
正式回答:是的,有些情况下你可以这样做(见@interjay的回答)。
实际答案:请不要那样做。真的。主要是直路可用时:
b.a.foo();
换句话说,如果至少有极小的机会避免类型转换,就不要使用它们。
如果您对 C++98,2003 感兴趣:
Q1 和 Q2 是相同的结构。
您的类型是PODs。 POD在实例化过程中开头没有填充是存在保证....但在继承过程中不存在保证。所以 reinterpret_cast 是不安全的... my question about POD layout
"In real life" 比较安全,因为大部分编译器都是在继承的时候进行内存布局的,比如http://phpcompiler.org/articles/virtualinheritance.html
但请注意 A 对象基地址 和 B 对象基地址 可能具有不同值的风险。