If all accesses to a data structure were done with read and write actions that transferred a whole field at a time, a program could not determine whether it was executing on a big-endian or little-endian system. For example, a word-sized access to field A in Figure A-1 would always get the correct value.
Suppose that the code shown in Listing A-1 is used to initialize the descriptor shown in Figure A-1. The field values chosen in Listing A-1 are encoded: the first nibble gives the size of the field, and the other nibbles represent the byte offsets of each byte, assuming big-endian ordering.
Listing A-1 Field value initializer
DMA_Descriptor aDescr;
aDescr.C = 0x10;
aDescr.F = 0x11;
aDescr.L = 0x2223;
aDescr.A = 0x44454647;
aDescr.X = 0x88898A8B8C8D8E8F;
In Figure A-1, all accesses to field aDescr.L would yield identical results on either a big-endian or little-endian system, so it would normally be impossible to tell whether the system was big-endian or little-endian. However, certain code can detect the order of byte significance relative to the address of the fields initialized by the code shown in Listing A-1 and can thus tell whether the system addresses data in big-endian or little-endian mode. An example is shown in Listing A-2.
Listing A-2 Endian mode determination code
union {
half H;
byte B[2];
} halfTrick;
halfTrick ht;
ht.H = aDescr.L;
if( ht.B[0] == 0x22 )
printf( "I'm on a big-endian system" );
else
printf( "I'm on a little-endian system" );