You cannot cast an arbitrary char*
to uint32_t*
, even if it points to an array large enough to hold a uint32_t
There are a couple reasons why.
The practical answer:
uint32_t
generally likes 4-byte alignment: its address should be a multiple of 4.
char
does not have such a restriction. It can live at any address.
That means that an arbitrary char*
is unlikely to be aligned properly for a uint32_t
.
The Language Lawyer answer:
Aside from the alignment issue, your code exhibits undefined behavior because you're violating the strict aliasing rules. No uint32_t
object exists at the address you're writing to, but you're treating it as if there is one there.
In general, while char*
may be used to point to any object and read its byte representation, a T*
for any given type T
, cannot be used to point at an array of bytes and write the byte-representation of the object into it.
No matter the reason for the error, the way to fix it is the same:
If you don't care about treating the bytes as a uint32_t
and are just serializing them (to send over a network, or write to disk, for example), then you can std::copy
the bytes into the buffer:
char buffer[BUFFER_SIZE] = {};
char* buffer_pointer = buffer;
uint32_t foo = 123;
char* pfoo = reinterpret_cast<char*>(&foo);
std::copy(pfoo, pfoo + sizeof(foo), buffer_pointer);
buffer_pointer += sizeof(foo);
uint32_t bar = 234;
char* pbar = reinterpret_cast<char*>(&bar);
std::copy(pbar, pbar + sizeof(bar), buffer_pointer);
buffer_pointer += sizeof(bar);
// repeat as needed
If you do want to treat those bytes as a uint32_t
(if you're implementing a std::vector
-like data structure, for example) then you will need to ensure the buffer is properly-aligned, and use placement-new:
std::aligned_storage_t<sizeof(uint32_t), alignof(uint32_t)> buffer[BUFFER_SIZE];
uint32_t foo = 123;
uint32_t* new_uint = new (&buffer[0]) uint32_t(foo);
uint32_t bar = 234;
uint32_t* another_new_uint = new (&buffer[1]) uint32_t(foo);
// repeat as needed