假设我们有两种类型,它们具有相同的表示形式(相同的成员变量和基类,并且顺序相同)。它们之间的reinterpret_cast是否有效(即不是UB)?例如。从reinterpret_castMaryAshley&有效吗?如果这两种类型是多态的怎么办?

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:


MaryAshley是对象类型,因此指向它们的指针可以相互转换。现在,我们使用Ashley类型的左值访问基础Mary对象。

[basic.lval]/8:



这些都没有涵盖所涉案件。 (“类似”讨论简历资格。)因此,行为不确定。

09-10 04:25
查看更多