非数组类型的指针算术 [英] Pointer arithmetics on non-array types
问题描述
让我们考虑下面的代码:
struct Blob {
double x,y,z;
} blob;
char * s = reinterpret_cast< char *>(& blob);
s [2] ='A';
假设sizeof(double)为8,这个代码是否触发未定义的行为?
从N4140(大致为C ++ 14)引用:
3.9类型[basic.types]
2对于任何可以复制类型的对象(基类子对象除外) code> T ,无论对象是否保存类型
T
的有效值,组成对象的底层字节可以复制到char
或unsigned char
的数组。 42 将char
或unsigned char
的数组复制回对象,对象将随后保持其原始值。 / p>
42)通过使用例如库函数(17.6.1.2)
std :: memcpy
或std :: memmove
。
3对于任何简单可复制类型
T
,如果指向T
的两个指针指向T
对象obj1
和obj2
,其中obj1
或obj2
如果组成obj1
的底层字节(1.7)被复制到obj2
, 43obj2
将随后保持与obj1
相同的值。 [示例: ...]
43)通过使用例如库函数(17.6.1.2)
std :: memcpy
或std :: memmove
。
$ b b
这原则上允许直接赋值给 s [2]
,如果你采取赋值给 s [2] / code>间接地需要等效于将所有其他一些
Blob
复制到只是恰好相同的数组,除了第三个字节,并且复制它进入你的 Blob
:你没有分配到 s [0]
, s [ 1]
等。对于包括 char
的简单可复制类型,这相当于将它们设置为它们已经具有的确切值,
但是,如果获取 s [2] =='A'
的唯一方法是内存操作,那么一个有效的参数也可以做,你复制回 Blob
不是组成的底层字节任何先前的 Blob
。在这种情况下,技术上,行为将是未定义的遗漏。
我强烈怀疑,特别是考虑到对象是否保存有效的类型 T
,即表示允许。
Let's consider following piece of code:
struct Blob {
double x, y, z;
} blob;
char* s = reinterpret_cast<char*>(&blob);
s[2] = 'A';
Assuming that sizeof(double) is 8, does this code trigger undefined behaviour?
Quoting from N4140 (roughly 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 typeT
, the underlying bytes (1.7) making up the object can be copied into an array ofchar
orunsigned char
.42 If the content of the array ofchar
orunsigned 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
orstd::memmove
.3 For any trivially copyable type
T
, if two pointers toT
point to distinctT
objectsobj1
andobj2
, where neitherobj1
norobj2
is a base-class subobject, if the underlying bytes (1.7) making upobj1
are copied intoobj2
,43obj2
shall subsequently hold the same value asobj1
. [ Example: ... ]43) By using, for example, the library functions (17.6.1.2)
std::memcpy
orstd::memmove
.
This does, in principle, allow assignment directly to s[2]
if you take the position that assignment to s[2]
is indirectly required to be equivalent to copying all of some other Blob
into an array that just happens to be bytewise identical except for the third byte, and copying it into your Blob
: you're not assigning to s[0]
, s[1]
, etc. For trivially copyable types including char
, that is equivalent to setting them to the exact value they already have, which also has no observable effect.
However, if the only way to get s[2] == 'A'
is by memory manipulation, then a valid argument could also be made that what you're copying back into your Blob
isn't the underlying bytes that made up any previous Blob
. In that case, technically, the behaviour would be undefined by omission.
I do strongly suspect, especially given the "whether or not the object holds a valid value of type T
" comment, that it's intended to be allowed.
这篇关于非数组类型的指针算术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!