有关如何通过xvalue访问对象值的示例,以便激发UB,如C ++ 11标准中的3.10 / 10所述

时间:2014-12-15 20:20:54

标签: c++ c++11 strict-aliasing

3.10 / 10

  

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

     
      
  • 对象的动态类型,
  •   
  • 对象的动态类型的cv限定版本,
  •   
  • 与对象的动态类型相似的类型(如4.4中所定义)
  •   
  • 与对象的动态类型对应的有符号或无符号类型的类型
  •   
  • 与对象的动态类型的cv限定版本对应的有符号或无符号类型的类型,
  •   
  • 聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(包括,   递归地,子聚合的子元素或非静态数据成员   包含联盟),
  •   
  • 一种类型,它是对象动态类型的(可能是cv限定的)基类类型,
  •   
  • char或unsigned char类型。
  •   

1 个答案:

答案 0 :(得分:-5)

读者应该知道OP引用的段落是宗教问题,是g ++编译器有争议行为的基础。任何对该段落的准确性或完整性产生怀疑的答案(并且都不是)都会在SO上被忽视。

根据你引用的段落,这是UB的一个例子:

struct X { int i; };

auto main() -> int
{
    X o{ 0 };
    return reinterpret_cast<int&>( o );
}

按顺序考虑C ++11§3.10/ 10中的每种可能性:

  • “对象的动态类型”oint吗? ,动态类型为X

  • int或许是动态类型X的“ cv - 限定版本”吗? X不是int cv - 是否已获得资格。

  • int“与对象的动态类型类似(如4.4所定义)类型吗?”
    再次,。 4.4处理多级 cv 资格。

  • 那么,int是一种类型,它是与对象动态类型对应的有符号或无符号类型吗? ,没有像X这样的类类型的已签名或无符号版本。

  • 那么“与对象的动态类型的cv限定版本相对应的有符号或无符号类型的类型”呢?

  • 嗯,int或许是“聚合或联合类型,其中包含其元素或非静态数据成员中的上述类型之一(包括递归地,元素或非静态数据成员)分段或包含联盟)“?
    ,而不是。

  • 所以也许int是一个类型,它是一个(可能是cv限定的)对象动态类型的基类类型? int不能是基类。

  • 最后,int是“char还是unsigned char类型”?

这耗尽了所有可能性,证明了根据 段落的隔离,此代码具有未定义的行为。

但是,此代码保证可以使用标准的另一部分(我猜主要是为了C兼容性)。

因此,即使对于完全独立于平台的正式,您引用的段落也不是100%好。


编辑:“dyp”在评论中询问这与使用xvalue有何关系。 xvalue是一个glvalue,因此可以用xvalue替换左值表达式o。这种xvalue的一个例子是从函数返回的右值引用,例如,来自std::move

#include <utility>
using std::move;

struct X { int i; };

template< class T >
auto ref( T&& r ) -> T& { return r; }

auto main() -> int
{
    X o{ 0 };
    return reinterpret_cast<int&>( ref( move( o ) ) );
}

然而,这一切都掩盖了必需品。