有关如何通过 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
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 ) ) );
}
然而,所有这些都是为了掩盖本质。
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- C++11 标准是否保证零值有符号整数的一元减号为零?
- 使用C++11标准的哪些规则来确定({..})中表达式的类型
- 在 C++11 标准中,为什么要依赖 char 类型实现?
- C++11 标准中的哪一部分规定了基元数据类型大小之间的相对顺序?
- 关于使用C 11标准编制C 98代码
- 即使明确指定了98个标准,GCC也使用C 11标准
- Visual Studio 2015 c++ 项目错误 c++11 标准
- C++14/17 项目可以使用使用 C++11 标准编译的二进制库还是需要重新编译源代码
- 由于 C++11 标准导致的标头中的 QtGStreamer 编译时错误?
- C++11标准是否保证"auto n2 = const_cast<int&>(n);" "n2 is int&"?
- C++11 标准::运行时有条件?
- C++11 标准::to_string(双) - 无尾随零
- 在C++11标准中,它在哪里指定了在翻译过程中何时可以计算constexpr函数
- C++11 标准是否保证跨实现的同一种子具有相同的随机数?
- 转到新的 c++11 标准
- 如何告诉SCONS使用C 11标准
- C++11 标准中的哪些条款允许我消除下面“A::operator-()”中“返回”语句中的“A”
- C++11 标准::regex_match 返回额外的字符