Reputation: 1434
I am taking a uint32_t value and extracting it into four uint8_t values. My code works with gcc 4.9, but I don't know how portable it is.
This works:
uint32_t u32 = 0xdeadbeef;
uint8_t byte3 = (uint8_t)(u32 >> 24); // 0xde
uint8_t byte2 = (uint8_t)(u32 >> 16); // 0xad
uint8_t byte1 = (uint8_t)(u32 >> 8); // 0xbe
uint8_t byte0 = (uint8_t)u32; // 0xef
Is this standards-compliant? Or should I be more explicit like so:
uint32_t u32 = 0xdeadbeef;
uint8_t byte3 = (uint8_t)((u32 & 0xFF000000) >> 24);
uint8_t byte2 = (uint8_t)((u32 & 0x00FF0000) >> 16);
uint8_t byte1 = (uint8_t)((u32 & 0x0000FF00) >> 8);
uint8_t byte0 = (uint8_t)(u32 & 0x000000FF);
I'm using the casts to quiet the conversion warnings I receive when compiling with the -Wconversion switch.
Upvotes: 2
Views: 1617
Reputation: 154087
Both work and are compliant.
The mask-less uint8_t byte0 = (uint8_t)u32;
is cleaner.
Portability limited to systems that support uint32_t
and uint8_t
. (Certainly most do)
Upvotes: 3
Reputation: 6875
Your first option is totally fine! There is no need to clear the unneeded bits.
The lower unneeded bits will be removed by the shift right >>
operation and the upper unneeded bits will be removed by the casting (uint8_t)
.
Upvotes: 3