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

Example on how to access the value of an object through an xvalue, in order to provoke UB, as described in 3.10/10 in the C++11 Standard

本文关键字:C++11 标准 UB 访问 xvalue 何通过 对象      更新时间:2023-10-16

3.10/10

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

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

读者应该意识到,OP引用的段落是一个宗教问题,作为g++编译器有争议行为的基础。任何对这一段的准确性或完整性产生怀疑的答案(两者都不是(通常会被SO否决。

根据您引用的段落,以下是UB的示例:

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

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

  • "对象的动态类型"o int吗?
    不,动态类型是X

  • int可能是动态类型X的">CV合格版本"吗?
    X不是int,符合简历资格与否。

  • int是"与对象的动态类型类似的类型(如 4.4 中所定义("吗?
    再次,没有。4.4 处理多级简历资格。

  • 那么,int是"与对象的动态类型对应的有符号或无符号类型"吗?
    不,没有像 X 这样的类类型的有符号或无符号版本。

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

  • 那么,int可能是"在其元素或非静态数据成员中包含上述类型之一的聚合或联合类型(递归地包括子聚合或包含的联合的元素或非静态数据成员("?
    ,也不是那样。

  • 那么也许int"对象动态类型的(可能符合 cv 条件的(基类类型的类型"?
    不可以int不能是基类。

  • 最后,int是"char型还是unsigned char型"?
    没有

这用尽了所有可能性,证明根据段落孤立地,此代码具有未定义的行为。

但是,这段代码保证可以通过标准的另一部分工作(我猜主要是为了 C 兼容性(。

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


编辑:"dyp"在评论中询问这与使用xvalue有何关系。xvalue 是一个 glvalue,因此只需用 xvalue 代替 lvalue 表达式 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 ) ) );
}

然而,所有这些都是为了掩盖本质。