I'm curious about conventions for type-punning pointers/arrays in C++. Here's the use case I have at the moment:
Compute a simple 32-bit checksum over a binary blob of data by treating it as an array of 32-bit integers (we know its total length is a multiple of 4), and then summing up all values and ignoring overflow.
I would expect such an function to look like this:
uint32_t compute_checksum(const char *data, size_t size)
{
const uint32_t *udata = /* ??? */;
uint32_t checksum = 0;
for (size_t i = 0; i != size / 4; ++i)
checksum += udata[i];
return udata;
}
Now the question I have is, what do you consider the "best" way to convert data
to udata
?
C-style cast?
udata = (const uint32_t *)data
C++ cast that assumes all pointers are convertible?
udata = reinterpret_cast<const uint32_t *>(data)
C++ cast that between arbitrary pointer types using intermediate void*
?
udata = static_cast<const uint32_t *>(static_cast<const void *>(data))
Cast through a union?
union {
const uint32_t *udata;
const char *cdata;
};
cdata = data;
// now use udata
I fully realize that this will not be a 100% portable solution, but I am only expecting to use it on a small set of platforms where I know it works (namely unaligned memory accesses and compiler assumptions on pointer aliasing). What would you recommend?