【问题标题】:Strict aliasing exceptions explanations严格别名异常解释
【发布时间】:2018-03-04 18:30:30
【问题描述】:

cppreference.com 上严格别名规则的前两个例外说:

  • AliasedType 是(可能是 cv 限定的)DynamicType
  • AliasedType 和 DynamicType 都是(可能是多级的,可能在每一级都有 cv 限定)指向同一类型 T(C++11 起)的指针

我不清楚这些情况之间的区别。 例如:

struct B { virtual ~B() {} };
struct D : B {};

B* b = new D;
reinterpret_cast<D*>(b);

上面的代码是否适合这两种情况?

据我所知,AliasedTypeDynamicType 都是 D(第一种情况),它们是指向同一类型 D 的指针。

如果我错了,您能否为每个单独的案例提供示例并更清楚地解释差异?

【问题讨论】:

  • cppreference 在这里是错误的。无论对象的动态类型如何,您都不能reinterpret_cast 将基指针指向派生指针或返回,然后取消引用转换后的指针。
  • @n.m.你能提供任何对该标准的参考吗?
  • 6.9.2p4。 “如果...,两个对象 a 和 b 是指针可互转换的。”仅允许第一个基类子对象且仅当对象具有标准布局时。
  • static_castdynamic_cast(检查运行时间)可以工作时,为什么还要使用reinterpret_cast
  • 6.10p8 没有给你 reinterpret_cast 任何东西的许可。它说您可以通过其动态指针类型通过指向其基类之一的指针来访问对象。它并没有说它们必须通过 reinterpret_cast 相互转换(它不可能这么说,因为以这种方式实现继承和重新解释强制转换是不可能的,或者至少没有现有的实现以这种方式实现它们) .

标签: c++ inheritance reinterpret-cast strict-aliasing


【解决方案1】:

要理解那里的语句,您必须意识到DynamicType 指的是对象 的类型,AliasedType 指的是用于访问该值的表达式的类型。但是演员表本身不是从DynamicTypeAliasedType,而是从DynamicType*AliasedType*

现在,C++ 具有多级指针。 DynamicType 可以是一些 A*AliasedType 可以是一些 B*,可能是 cv 合格的。因此,DynamicType* 将是 A**。这就是为什么你需要第二种情况。 AliasedType 可以是 A const*,它不同于 A*。因此,它不在第一条规则中(A const* 不是 A* 的 cv 限定版本,与 A* const 不同)。

现在,至于您的代码:您的对象的DynamicTypeD,这从new D 非常明显。 D 不是指针类型,它是类类型。这意味着只有 cv 限定的变体可以给它起别名:volatile Dconst Dconst volatile D

但是,您没有指向该 D 对象的指针,您有一个指向其 B 子对象的指针。这个子对象可以用B const 等作为别名。

您正在做的是尝试使用AliasedTypeD 访问B 子对象。那是行不通的——D 不是 cv 合格的B。它们通过继承而不是 cv 限定相关。

【讨论】:

  • 引用也是允许的。但是对于这两种情况的真实例子呢?我的代码与@n.m 完全错误吗?说?
  • @alexolut:是的。
  • 您能否在上述两种情况的答案中添加正确的代码 sn-ps?我认为答案将在那种情况下完成,我可以接受。
猜你喜欢
  • 2021-07-04
  • 2014-02-08
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 2023-01-11
相关资源
最近更新 更多