您可以在具有相同表示形式的类型之间进行reinterpret_cast吗? [英] Can you reinterpret_cast between types which have the same representation?

查看:64
本文介绍了您可以在具有相同表示形式的类型之间进行reinterpret_cast吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Suppose we have two types, that have the same representation (the same member variables and base classes, in the same order). Is it valid (i.e. not UB) to reinterpret_cast between them? E.g. is it valid to reinterpret_cast from Mary to Ashley&? And what if the two types are polymorphic?

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)吗?

What if we cast the beginning of an object to another type, if we know that the source type starts with the member variables of the target type? E.g. is this valid (i.e. not 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;
}

请注意,所有主要的编译器都将其视为有效的强制转换(实时演示).问题是,C ++语言是否允许这样做.

Note that all major compilers treat these as a valid casts (live demo). The question is, whether the C++ language allows this.

推荐答案

可以将类型为 T1 的glvalue表达式强制转换为引用"类型如果可以显式地指定类型为" T1 的指针"的表达式,则返回 T2 "使用 reinterpret_cast 转换为指向 T2 的指针"类型.结果指向与源glvalue相同的对象,但是带有指定的类型.[...]

A glvalue expression of type T1 can be cast to the type "reference to T2" if an expression of type "pointer to T1" can be explicitly converted to the type "pointer to T2" using a reinterpret_­cast. The result refers to the same object as the source glvalue, but with the specified type. [...]

Mary Ashley 是对象类型,因此指向它们的指针可以相互转换.现在,我们使用类型为 Ashley lvalue 来访问基础的 Mary 对象.

Mary and Ashley are object types, so pointers thereto can convert to each other. Now, we get use a lvalue of type Ashley to access the underlying Mary object.

[basic.lval]/8 :

如果程序尝试通过以下方式访问对象的存储值除以下类型之一以外的glvalue的行为是未定义:

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

  • 对象的动态类型

  • the dynamic type of the object,

对象动态类型的cv限定版本,

a cv-qualified version of the dynamic type of the object,

与对象的动态类型相似的类型

a type similar to the dynamic type of the object,

一种类型,它是与对象的动态类型相对应的有符号或无符号类型

a type that is the signed or unsigned type corresponding to the dynamic type of the object,

一种类型,它是与对象的动态类型的cv限定版本相对应的有符号或无符号类型

a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,

一种聚集或联合类型,在其元素或非静态数据成员(包括,递归地表示子聚合或包含工会),

an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),

一种类型,它是对象动态类型的(可能是cv限定的)基类类型,

a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,

一种 char unsigned char std :: byte 类型.

这些都没有涵盖所讨论的案件.(类似"讨论简历资格.)因此,存在不确定的行为.

None of these covers the case in question. ("Similar" talks about cv-qualification.) Therefore, undefined behavior.

这篇关于您可以在具有相同表示形式的类型之间进行reinterpret_cast吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆