c++ - 非数组类型的指针算法

标签 c++ language-lawyer type-punning char-pointer

让我们考虑以下代码:

struct Blob {
    double x, y, z;
} blob;

char* s = reinterpret_cast<char*>(&blob);
s[2] = 'A';

假设 sizeof(double) 是 8,这段代码会触发未定义的行为吗?

最佳答案

引自 N4140(大致为 C++14):

3.9 Types [basic.types]

2 For any object (other than a base-class subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char.42 If the content of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its original value.

42) By using, for example, the library functions (17.6.1.2) std::memcpy or std::memmove.

3 For any trivially copyable type T, if two pointers to T point to distinct T objects obj1 and obj2, where neither obj1 nor obj2 is a base-class subobject, if the underlying bytes (1.7) making up obj1 are copied into obj2,43 obj2 shall subsequently hold the same value as obj1. [ Example: ... ]

43) By using, for example, the library functions (17.6.1.2) std::memcpy or std::memmove.

原则上,如果您认为对 s[2] 的赋值间接要求等同于将所有其他 Blob 复制到一个数组中,该数组恰好除了第三个字节外字节相同,并将其复制到您的 Blob 中:您没有分配给 s[0]s[1] 等。对于包括 char 在内的平凡可复制类型,这相当于将它们设置为它们的确切值已经有了,也没有明显的效果。

但是,如果获取 s[2] == 'A' 的唯一方法是通过内存操作,那么也可以提出一个有效的论点,即您正在复制回您的 Blob 不是构成任何先前 Blob 的底层字节。在那种情况下,从技术上讲,行为将因遗漏而未定义。

我强烈怀疑,尤其是考虑到“该对象是否拥有 T 类型的有效值”注释,它是有意被允许的。

关于c++ - 非数组类型的指针算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34879858/

相关文章:

c++ - 在 C++03 中通过 int 传输 double 是否安全?

c - C中临时对象的有效类型

c++ - setstylesheet 不单独设置属性

c++ - 在 OpenCV 中分配矩阵元素

oop - 具有伴随对象的类与具有相同名称的类和对象之间有什么区别?

c++ - 为什么在没有初始化的情况下获取string[0]也是有效的?

c++ - 用于匹配 C++ 字符串常量的正则表达式

c++ - MF 不播放来 self 的来源的视频

c++ - 在重载选择期间不考虑默认参数的转换?

c++ - 通过 constexpr union 进行类型双关