This is a common way to read the bytes of an trivially copyable object
Object obj;
auto p = reinterpret_cast<char*>(&obj);
for(size_t i = 0; i < sizeof(obj); i++)
consume(p[i]);
The problem isn't with strict-aliasing, char*
is allowed to alias anything. The problem is with this passage from [expr.add]
When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression
P
points to elementx[i]
of an array objectx
withn
elements, the expressionsP + J
andJ + P
(whereJ
has the valuej
) point to the (possibly-hypothetical) elementx[i + j]
if0 ≤ i + j ≤ n
; otherwise, the behavior is undefined. Likewise, the expressionP - J
points to the (possibly-hypothetical) elementx[i − j]
if0 ≤ i − j ≤ n
; otherwise, the behavior is undefined.
Where hypothetical element refers to
A pointer past the last element of an array
x
ofn
elements is considered to be equivalent to a pointer to a hypothetical elementx[n]
for this purpose
Which is to say, it is only legal if the arithmetic is on a pointer pointing at an array, and the result is still within its range.
However, there is clearly no char[sizeof(Object)]
here, can we do arithmetic on that pointer?
Note that a legal solution to reading bytes of an object is to std::memcpy
the object. But if that is the only solution, it begs to ask, why allow char*
aliasing if you can barely do anything with it?