3.10 / 10
如果程序试图通过访问对象的存储值 行为是除以下类型之一以外的glvalue 未定义:
- 对象的动态类型,
- 对象的动态类型的cv限定版本,
- 与对象的动态类型相似的类型(如4.4中所定义)
- 与对象的动态类型对应的有符号或无符号类型的类型
- 与对象的动态类型的cv限定版本对应的有符号或无符号类型的类型,
- 聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(包括, 递归地,子聚合的子元素或非静态数据成员 包含联盟),
- 一种类型,它是对象动态类型的(可能是cv限定的)基类类型,
- char或unsigned char类型。
答案 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中的每种可能性:
“对象的动态类型”o
是int
吗?
否,动态类型为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 ) ) );
}
然而,这一切都掩盖了必需品。