bitsmack
bitsmack

Reputation: 1434

Portable method to extract uint8_t bytes from uint32_t values in c

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

Answers (2)

chux
chux

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

Alex Lop.
Alex Lop.

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

Related Questions