I have some C code that parses packed/unpadded binary data that comes in from the network.
This code was/is working fine under Intel/x86, but when I compiled it under ARM it would often crash.
The culprit, as you might have guessed, was unaligned pointers -- in particular, the parsing code would do questionable things like this:
uint8_t buf[2048];
[... code to read some data into buf...]
int32_t nextWord = *((int32_t *) &buf[5]); // misaligned access -- can crash under ARM!
... that's obviously not going to fly in ARM-land, so I modified it to look more like this:
uint8_t buf[2048];
[... code to read some data into buf...]
int32_t * pNextWord = (int32_t *) &buf[5];
int32 nextWord;
memcpy(&nextWord, pNextWord, sizeof(nextWord)); // slower but ARM-safe
My question (from a language-lawyer perspective) is: is my "ARM-fixed" approach well-defined under the C language rules?
My worry is that maybe even just having a misaligned-int32_t-pointer might be enough to invoke undefined behavior, even if I never actually dereference it directly. (If my concern is valid, I think I could fix the problem by changing pNextWord
's type from (const int32_t *)
to (const char *)
, but I'd rather not do that unless it's actually necessary to do so, since it would mean doing some pointer-stride arithmetic by hand)