You should not do this. Many architectures have data alignment requirements. For example, dereferencing a pointer not aligned to a word boundary on a SPARC machine, will crash the program with a Bus Error (SIGBUS
).
The portable way to split your int
into bytes is by using bitwise operations (assuming 8-bit bytes):
uint8_t b3 = 0x12, b2 = 0x34, b1 = 0x56, b0 = 0x78;
uint32_t a;
a = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
printf("%08X\r\n", a);
a = 0x89ABCDEF;
b3 = (a >> 24) & 0xFF;
b2 = (a >> 16) & 0xFF;
b1 = (a >> 8) & 0xFF;
b0 = a & 0xFF;
printf("%02X%02X%02X%02X\r\n", b3, b2, b1, b0);
The same can be non-portably achieved with type punning tricks through union
s, such as:
typedef union {
uint32_t val;
uint8_t bytes[4];
} DWORD_A;
typedef union {
uint32_t val;
struct {
unsigned b0:8;
unsigned b1:8;
unsigned b2:8;
unsigned b3:8;
};
} DWORD_B;
However, this technique leads to implementation defined behaviour and thus is not recommended:
- Byte order depends on host system's endianness.
- Packing of the bit fields is not portable.
- Added complexity/overhead due to code generated by the compiler to prevent misaligned access.
- Alignment issues, on implementations that don't prevent them.