让我们考虑以下代码:
struct Blob {
double x, y, z;
} blob;
char* s = reinterpret_cast<char*>(&blob);
s[2] = 'A';
假设sizeof(double)为8,此代码是否会触发未定义的行为?
答案 0 :(得分:5)
引自N4140(大致是C ++ 14):
3.9类型[basic.types]
2对于普通可复制类型
T
的任何对象(基类子对象除外),无论对象是否包含类型T
的有效值,基础字节(1.7)都会生成可以将对象复制到char
或unsigned char
的数组中。 42 如果复制了char
或unsigned char
数组的内容回到物体后,物体应随后保持其原始值。42)例如,使用库函数(17.6.1.2)
std::memcpy
或std::memmove
。3对于任何简单的可复制类型
T
,如果指向T
的两个指针指向不同的T
个对象obj1
和obj2
,则obj1
如果复制构成obj2
的基础字节(1.7),则{} {} {}为基类子对象 进入obj1
, 43obj2
随后应保持与obj2
相同的值。 [示例: ...]43)例如,使用库函数(17.6.1.2)
obj1
或std::memcpy
。
原则上,如果您认为间接要求将std::memmove
的分配等同于将所有其他s[2]
复制到一个s[2]
,则允许直接分配到Blob
。除了第三个字节之外,恰好是字节相同的数组,并将其复制到Blob
:你没有分配给s[0]
,s[1]
等。用于简单的可复制类型包括char
,相当于将它们设置为已有的确切值,这也没有可观察到的效果。
但是,如果获取s[2] == 'A'
的唯一方法是通过内存操作,那么也可以使用有效的参数将您复制回Blob
的内容isn&# 39; t 构成任何先前Blob
的基础字节。在这种情况下,从技术上讲,行为将因遗漏而不明确。
我强烈怀疑,特别是考虑到&#34;对象是否包含T
&#34类型的有效值;评论,它是打算被允许的。
答案 1 :(得分:0)
该标准的第3.10章似乎允许该特定情况,假设&#34;访问存储的值&#34;意思是&#34;读或写&#34;,这是不清楚的。
3.10-10
如果程序试图通过访问对象的存储值 行为是除以下类型之一以外的glvalue 理解过程科幻奈德强>:
- (10.1)对象的动态类型
- (10.2)对象的动态类型的cv-quali fi ed版本,
- (10.3)与动态类型类似的类型(如4.4中所定义) 对象,
- (10.4)对应的有符号或无符号类型的类型 对象的动态类型,
- (10.5)对应于a的有符号或无符号类型的类型 cv-quali fi ed版本的对象的动态类型,
- (10.6)包含其中一个的聚合或联合类型 上述类型的元素或非静态数据成员 (递归地,包括a的元素或非静态数据成员) subaggregate或contains union),
- (10.7)一种类型,它是(可能是cv-quali fi ed)的基类类型 对象的动态类型,
- (10.8) char或unsigned char类型。