This fragment of code:
#include <stdio.h>
int main() {
int a = 130;
char *ptr;
ptr = (char *)&a;
printf("%d ",*ptr);
return 0;
}
doesn't have undefined or unspecified behaviour, besides the quite obscure possibility that 130 would somehow happen to be trap value when accessed as (implicitly signed) char, but there are many possible outcomes:
- output is
-126 on a little-endian platform where char is signed and the representation is 2's complement
- output is something else on an architecture that uses sign-and-magnitude or one's complement for the negative numbers.
- output is
130 on a little-endian platform where char is unsigned.
- output is
0 on a big-endian platform where char is signed or unsigned
- output could be
0 on a middle-endian platform. Or it could be -126 or 130 or something else if int is represented by one, two bytes
- there are platforms where
sizeof(int) is 1. It might be that all addressable primitive values have sizeof 1 - these wouldn't then have any endianness at all.
Some of these are obscure, but both little- and big-endian computers do exist widely, and on ARM processors the chars are unsigned by default.
To not complicate things too much, the endianess detection ought to be done using unsigned types.
The union test works if you use fixed-size types
union {
uint32_t the_int;
uint8_t fragments[4];
}
You wouldn't test the endianness of your computer at runtime! The code has to be compiled for one and one endianness only so you can do it at compile-time anyway. The actual endianness checks that need to be done at runtime concern only data structures read from files or interprocess communication.