I'm confused about whether or not this is a strict aliasing violation or invokes undefined behavior. Multiple people have told me it's not a violation and that there is no UB, but from reading the C++ spec it sounds like doing anything that dereferences a type-casted pointer (unless it was just cv-casted or casted to a compatible type or char) is UB.
#define SWAP(x) (((x) << 8) | ((x) >> 8)))
char* foo(char* data, size_t len16) {
int align = reinterpret_cast<uintptr_t>(data) % sizeof(uint16_t);
if (align == 0) {
uint16_t* data16 = reinterpret_cast<uint16_t*>(data);
for (size_t i = 0; i < len16; i++) {
data16[i] = SWAP(data16[i]);
}
} else {
throw "Unaligned";
}
return data;
}
(This is a slightly contrived example; in reality SWAP
may be a third-party function that requires a uint16_t
.)
Is the story changed because we've checked alignment, are confident about the size of the types and don't care about endianness? The remaining concern would, I guess, be dead code elimination by the optimizer.
If this is illegal, how would you efficiently interpret a char
buffer (e.g. from a file) as its intended type (e.g. int16
s)? I'm familiar with casting through a union, but I don't really see how that's any different (see casting through a union(1), aside from telling the compiler that it cannot do dead code elimination.