这是读取普通可复制对象的字节的常用方法
Object obj;
auto p = reinterpret_cast<char*>(&obj);
for(size_t i = 0; i < sizeof(obj); i++)
consume(p[i]);
问题不在于严格别名,char*
允许别名。这个问题来自[expr.add]
当向指针添加或从指针中减去具有整数类型的表达式时,结果具有指针操作数的类型。如果表达式
P
指向具有x[i]
元素的数组对象x
的元素n
,则表达式P + J
和J + P
(其中{{ 1}}具有值J
)指向(可能是假设的)元素j
ifx[i + j]
;否则,行为未定义。同样,如果0 ≤ i + j ≤ n
,表达式P - J
指向(可能是假设的)元素x[i − j]
;否则,行为未定义。
假设元素指的是
指向
0 ≤ i − j ≤ n
元素的数组x
的最后一个元素的指针被认为等同于指向假设元素n
的指针
也就是说,如果算术是指向数组的指针,结果仍然在其范围内,那么这是合法的。
但是,这里显然没有x[n]
,我们可以对该指针进行算术运算吗?
请注意,读取对象字节的合法解决方案是char[sizeof(Object)]
对象。但是,如果那是唯一的解决方案,那么就要问,为什么如果你几乎无法使用它来允许std::memcpy
别名?
答案 0 :(得分:1)
根据引号,指针算法应该是合法的。 Object
实例obj
可以被视为char[sizeof(Object)]
。因此,它是一个n
元素数组(请注意n
是sizeof(Object)
)。 Standard允许在此数组的范围内进行指针运算加上超出此数组边界的一个假设元素。这是由于
0≤i+j≤n
表达。
从字面上看,reinterpret_cast<char*> (&obj) + sizeof(Object)
很好,因为它指向假设元素a[j]
,其中j = sizeof(Object)
并且小于或等于而不是数组的大小,是sizeof(Object)
。
所以,答案是肯定的。
否则数组的std::end
将为UB。