Given the following code:
unsigned char *packet_data = (unsigned char *)malloc(7);
memset(packet_data, 0, 7);
uint16_t crc = 0xa8a9;
*((uint16_t *)&packet_data[5]) = (crc >> 8) | (crc << 8);
for (int i = 0; i < 7; i++) {
printf("%02X ", packet_data[i]);
}
printf("\n");
On my Mac (x86_64), the output is, as expected, 00 00 00 00 00 A8 A9 (A8 goes in byte 5 (counting from 0)). Compiled with clang (LLVM 7.3.0)
On an armv5tejl machine, the output is, however, 00 00 00 00 A8 A9 00 (A8 goes in byte 4 (counting from 0)). In this case, if we switch 5 to 4 on the source code the exact same output will come out. Compiled with gcc 4.6.3, like this on the Godbolt compiler explorer.
Both machines are little endian.
Why does this happen?
Assuming alignment requirement for the type uint16_t is 2, then your code has undefined behavior1, as this pointer: (uint16_t *)&packet_data[5] isn't correctly aligned.
If you use an aligned offset, like 4, the results should be the same as the behavior is defined.
1 (Quoted from: ISO/IEC 9899:201x 6.3.2.3 Pointers 7):
A pointer to an object type may be converted to a pointer to a different object type. If the
resulting pointer is not correctly aligned for the referenced type, the behavior is
undefined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With