【问题标题】:Is it undefined behavior to reinterpret_cast an object of an unrelated type to an empty class将不相关类型的对象重新解释为空类是未定义的行为吗
【发布时间】:2018-06-24 16:33:18
【问题描述】:

将不相关的类型转换为空的基类是未定义的行为吗?然后使用该地址构造一个继承自该空基的派生类型?例如

class Derived : public EmptyBase {
public:
    template <typename T>
    Derived(T&& t) : EmptyBase{std::forward<T>(t)} {}
    using EmptyBase::print;
};

然后做这样的事情是不确定的

static auto shim = 1;
auto derived = Derived{*reinterpret_cast<EmptyBase*>(&shim)};
derived.print();

标准保证必须在标准布局结构中优化空基,但不确定是否允许这样的东西构造派生类

【问题讨论】:

  • 这段代码对我来说毫无意义。你想完成什么?
  • @MarkRansom 我认为当我使用 language-lawyer 标签时问这个问题不合适。您应该相信提出问题的人在可能难以在堆栈溢出帖子中解释的利基情况下需要这样的东西,特别是考虑到他们已经证明已经尝试围绕该主题进行研究。此外,多次用这样的方式详细解释用例与帖子无关。哪一部分对您来说没有意义?
  • @Curious 我的意思是我所说的 - 我很难理解代码。如果我不能理解它,我无法回答它。只是一点背景可能会有很长的路要走。

标签: c++ c++11 language-lawyer undefined-behavior reinterpret-cast


【解决方案1】:
Derived{*reinterpret_cast<EmptyBase*>(&shim)}

Derived 的构造函数访问其参数的值表示来初始化其基类。该参数的类型为EmptyBase&amp;&amp;。但是该地址没有EmptyBase 对象;该地址有一个int

因此,您正在通过与int 无关的类型的泛左值 (EmptyBase&amp;&amp;) 访问 int 的值表示。这违反了严格的别名。

所以不,你不能这样做。

不,EmptyBase 没有子对象并不重要。复制对象访问其值表示。即使派生类会覆盖它所做的任何事情(因为空的基类没有自己的存储空间)。

【讨论】:

  • 如果代码被修改为(只是为了让 OP 的代码编译):i.imgur.com/IH2dwnt.png 则不使用传入的参数..
  • @Brandon:执行演员表不是问题发生的地方。当您使用非法转换的结果时,您会得到 UB。如果一个糟糕的演员掉进树林而没有人听到,你就不会得到 UB。
  • 在其构造函数中实际上不使用引用的空基类是否仍会导致 UB?那不访问值表示?
  • 添加EmptyBase(EmptyBase&amp;&amp;){} ctor 会发生什么?我问这个是因为它符合 OP 的标题,如果不是例子的话。
  • 你能解释一下为什么复制一个空对象需要访问它吗?
猜你喜欢
  • 2017-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-28
  • 1970-01-01
  • 2011-11-24
  • 2021-07-30
  • 1970-01-01
相关资源
最近更新 更多