以下 reinterpret_cast 是否会导致未定义的行为? [英] Does the following reinterpret_cast lead to undefined behavior?

查看:80
本文介绍了以下 reinterpret_cast 是否会导致未定义的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面代码中的 reinterpret_cast 是否会导致未定义的行为?如果是,是否可以以类型安全的方式定义 rpd?

Does the reinterpret_cast in the code below lead to undefined behavior? In case it does, is it possible to define rpd in a type-safe manner?

class Base
{ 
public:
  virtual ~Base() = default;
};

class Derived : public Base { };

int main(void)
{
  Derived d;
  Base* pb = &d;
  Base*& rpb = pb;

  Derived*& rpd = reinterpret_cast<Derived*&>(rpb);

  return 0;
}

与我之前的最近的问题有关.这背后的背景;我正在试验一个适配器类,它应该允许包含协变指针类型的向量本身用作协变类型.

Sort of related to my previous recent question. Context behind this; I am experimenting with an adapter class that should allow vectors containing covariant pointer types to be used as covariant types themselves.

推荐答案

演员表本身没有 UB(参见 [expr.reinterpret.cast]),但访问引用的指针(rpb) 通过重新解释的参考 (rpd) 执行:

The cast itself doesn't have UB (see [expr.reinterpret.cast]), but accessing the referred pointer (rpb) through the reinterpreted reference (rpd) does:

[basic.lval](标准草案)

[basic.lval] (standard draft)

如果程序尝试通过以下类型之一以外的泛左值访问对象的存储值,则行为未定义:56

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:56

56) 此列表的目的是指定对象可以或不可以别名的情况.

56) The intent of this list is to specify those circumstances in which an object may or may not be aliased.

  • (8.1)对象的动态类型,

不适用,动态类型是静态类型,即Base*,而不是Derived*,即泛左值的类型.

Does not apply, the dynamic type is the static type which is Base*, not Derived* that is the type of the glvalue.

  • (8.2)对象的动态类型的 cv 限定版本,

没有 cv 限定,类型仍然不匹配.

There are no cv-qualifications, and the types still don't match.

  • (8.3)一种类似于对象的动态类型的类型,

不适用.这是关于 cv 限定符的分解,参见 [conv.qual](抱歉,段落中的那么多下标在 html 中输入很麻烦,并且是保持文本可读性所必需的).

Does not apply. This is about cv-qualifier de-compositions, see [conv.qual] (sorry, those many subscripts in the paragraphs are a pain to type in html and are necessary to keep the text readable).

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

仅与整数类型相关.

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

同上.

  • (8.6)一种聚合或联合类型,在其元素或非静态数据成员中包含上述类型之一(递归地包括子聚合或包含联合的元素或非静态数据成员),

Derived* 既不是聚合也不是联合.

Derived* is neither an aggregate nor a union.

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

Derived* 不是 Base* 的基础.

  • (8.8)char、unsigned char 或 std :: byte 类型.

Derived* 不是这些.

由于没有任何例外情况,因此未定义通过 Derived* 类型的泛左值访问 Base* 的行为.

As none of the exceptions apply, the behaviour of accessing a Base* through a glvalue of Derived* type is undefined.

我正在试验一个适配器类,它应该允许包含协变指针类型的向量本身用作协变类型.

I am experimenting with an adapter class that should allow vectors containing covariant pointer types to be used as covariant types themselves.

您的实验将无法坚持面向对象的基本原则.

Your experiment would fail to uphold basic object oriented principles.

基引用与派生对象是协变的,因为您无法通过基引用对派生对象执行任何操作,而对派生对象本身则无法执行.

Base references are covariant with derived, because you cannot do anything with a derived object through a base reference that you couldn't do with the derived object itself.

基类型的容器不能与派生的容器协变,因为您可以对基类的容器(通过其引用"容器派生)做一些不能用派生的容器做的事情:添加对象其他派生类型.

Containers of base type cannot be covariant with containers of derived, because you can do something with a container of (derived through a "referencing" container of) base that you couldn't do with a container of derived: Add objects of other derived types.

虽然,如果容器是不可变的......它可能在概念上起作用.实际上用 C++ 实现它是另一回事.

Although, if the containers are immutable... it might work conceptually. Actually implementing it in C++ is another matter.

这篇关于以下 reinterpret_cast 是否会导致未定义的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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