1 #include <stdio.h> 2 3 main() { 4 int i; /* Loop variable */ 5 long x = 0xAABBCCDD; 6 unsigned char *ptr = (char *) &x; 7 8 /* Print value in host byte order */ 9 printf("x in hex: %x\n", x); 10 printf("x by bytes: "); 11 for (i=0; i < sizeof(long); i++) 12 printf("%x\t", ptr[i]); 13 printf("\n"); 14 } When compiled and run on an Intel server, which is an LE environment, the following is printed: x in hex: aabbccdd x by bytes: dd cc bb aa When compiled and run on an IBM Power server, which is a BE environment, the following is printed: x in hex: aabbccdd x by bytes: aa bb cc dd Note that the preceding example was compiled with gcc, which creates a 32-bit executable by default. Most RISC-based computers, including IBM PowerPC servers, and the Internet Protocol (IP) use a BE layout, whereas Intel and Alpha architectures utilize an LE layout. When porting software, it is recommended to watch out for endian issues, because most if not all of these issues may go undetected, resulting in hard-to-find problems when they occur. The problems in ported software include the following: Nonuniform data reference[20] [20] Example 3-6 shows nonuniform data reference using a pointer.
Data sharing across BE and LE platforms Data exchange between network devices (for example, IP and PCI)[21] [21] PCI devices use an LE format, which needs to be accounted for if porting the device driver to a BE platform.
Nonuniform data reference occurs more often in user space application code, whereas the latter two categories are difficulties encountered at lower code levels (for example, device drivers). Nonuniform data reference arises from improper data type reference with regard to endianness, usually dealing with unions or pointers. Endian-friendly code should incorporate definitions to determine whether the platform is LE or BE. It is considered a good programming habit to never cast a pointer to an int and to explicitly reference data type and byte values during conversion. |