Question

I don't understand why this code triggers off aliasing warning:

char buf[15];

*(uint16_t*) buf = 0x4040;

There is no any thinkable "alignments" within char type. And anyway, how do I do this in graceful way? So far I can't think of anything better than

char buf[15];
uint16_t foo = 0x4040;
memcpy(buf, &foo, 2);

The warning is this:

warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
Was it helpful?

Solution

There is no any thinkable "alignments" within char type.

And that's the problem, a char array normally have the smallest possible alignment requirement, of 1.

However your code tries to treat it as an uint16_t, which might have a different alignment requirement than 1 (typically 2).

The solution you have here is reasonable:

char buf[15];
uint16_t foo = 0x1234; //changed this to demonstrate endian issue
memcpy(buf, &foo, 2);

The caveat is with both these approaches is the content of buf will depend on the endian of your host, i.e. on a little endian system you will end up with

buf[0] == 0x34;
buf[1] == 0x12;

While on a big endian system the values will be reversed. If this is of no concern, then all is well. If it is a concern, instead of the memcpy() you could do:

 buf[0] = foo & 0xff;
 buf[1] = foo >> 8;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top