假设我们有两种类型,它们具有相同的表示形式(相同的成员变量和基类,并且顺序相同)。它们之间的reinterpret_cast
是否有效(即不是UB)?例如。从reinterpret_cast
到Mary
的Ashley&
有效吗?如果这两种类型是多态的怎么办?
struct Mary {
int m1;
char m2;
};
struct Ashley {
int a1;
char a2;
};
int TryTwins ()
{
Mary mary = {};
Ashley& ashley = reinterpret_cast<Ashley&> (mary);
ashley.a1 = 1;
ashley.a2 = 2;
return mary.m1 + mary.m2;
}
如果我们知道对象类型以目标类型的成员变量开头,那么将对象的开头转换为另一种类型怎么办?例如。这是有效的(即不是UB)吗?
struct Locomotive {
int engine;
char pantograph;
};
struct Train {
int engine;
char pantograph;
int* wagon1;
int** wagon2;
int*** wagon3;
};
int TryTrain ()
{
Train train = {};
Locomotive& loc = reinterpret_cast<Locomotive&> (train);
loc.engine = 1;
loc.pantograph = 2;
return train.engine + train.pantograph;
}
请注意,所有主要的编译器都将其视为有效的强制转换(live demo)。问题是,C++语言是否允许这样做。
最佳答案
[expr.reinterpret.cast]/11:
Mary
和Ashley
是对象类型,因此指向它们的指针可以相互转换。现在,我们使用Ashley
类型的左值访问基础Mary
对象。
[basic.lval]/8:
这些都没有涵盖所涉案件。 (“类似”讨论简历资格。)因此,行为不确定。