Incidentally, you can detect endianness very easily at runtime.
Code:
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
bool little_endian(void) {
static bool state = false;
static bool known = false;
if (!known) {
unsigned long sample = 0xff;
uint8_t* bytes = (uint8_t*)&sample;
if (bytes[0] == 0xff)
state = true;
known = true;
}
return state;
}
#define big_endian() !little_endian()
void reverse_bytes(void* data, size_t size) {
uint8_t* left = (uint8_t*)data;
uint8_t* right = left + size;
while (left < --right) {
uint8_t copy = *left;
*left++ = *right;
*right = copy;
}
}
void to_little_endian(void* data, size_t size) {
if (!little_endian())
reverse_bytes(data, size);
}
void to_big_endian(void* data, size_t size) {
if (!big_endian())
reverse_bytes(data, size);
}
#include <stdio.h>
int main(void) {
uint8_t a1[4] = {0x52, 0x4a, 0x75, 0xd8};
uint32_t x1 = *(uint32_t*)a1;
uint32_t y1 = 0x524a75d8;
printf("CPU is %s-endian\n", big_endian() ? "big" : "little");
printf("x=%x, y=%x, a=%02x%02x%02x%02x\n", x1, y1, a1[0], a1[1], a1[2],
a1[3]);
puts("Switching to big-endian format");
to_big_endian(a1, 4);
printf("x=%x, y=%x, a=%02x%02x%02x%02x\n", x1, y1, a1[0], a1[1], a1[2],
a1[3]);
uint8_t a2[4] = {0x52, 0x4a, 0x75, 0xd8};
uint32_t x2 = *(uint32_t*)a2;
uint32_t y2 = 0x524a75d8;
puts("Switching to little-endian format");
to_little_endian(a2, 4);
printf("x=%x, y=%x, a=%02x%02x%02x%02x\n", x2, y2, a2[0], a2[1], a2[2],
a2[3]);
}
Output on my machine:
CPU is little-endian
x=d8754a52, y=524a75d8, a=524a75d8
Switching to big-endian format
x=d8754a52, y=524a75d8, a=d8754a52
Switching to little-endian format
x=d8754a52, y=524a75d8, a=524a75d8