This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Robust detection of endianness at compile time.


This issue started in a previous thread, but I have studied it a bit more
and decided to create another thread with a more focused title.  Hopefully,
there is an expert in the readers of this forum that can explain the whys.

There doesn't appear to be a simple and robust (i.e., cross-platform) way of
determining the endianness of the underlying platform at compile-time.
There are a number of macro flags and variables which I have found which
appear to address this issue. A short list of these include: 

Numeric variables:
LITTLE_ENDIAN, __LITTLE_ENDIAN, __LITTLE_ENDIAN__ = 1234
BIG_ENDIAN, __BIG_ENDIAN, __BIG_ENDIAN__ = 4321
PDP_ENDIAN, __PDP_ENDIAN, __PDP_ENDIAN__ = 3412
BTYE_ORDER, __BYTE_ORDER, __BYTE_ORDER__ = <one of the above values>

Flags:
__IEEE_BIG_ENDIAN
__IEEE_LITTLE_ENDIAN
__IEEE_BYTES_LITTLE_ENDIAN.  

There appear to be 3 types of endianess: Big (=network), Little, and
PDP/ARM.  

If the numeric variables are to be trusted the way to test for endianness
would be something like this:

TEST1:
#include <endian.h>
#ifdef __BYTE_ORDER
  #if __BYTE_ORDER == __BIG_ENDIAN //if both are not defined it is TRUE!
    ...assume BIG ENDIAN...
  #elif __BYTE_ORDER == __LITTLE_ENDIAN
    ...assume LITTLE ENDIAN...
  #elif __BYTE_ORDER == __PDP_ENDIAN
    ...assume 3412 PDP/ARM...
  #else 
    #error "Endian determination failed"
  #endif
#endif

According to John (Eljay) Love-Jensen:  
...some platforms define this:
  #define __BIG_ENDIAN__ 0 
Which clearly doesn't follow the numeric scheme above and may fail depending
on how __BYTE_ORDER and the other macros are defined.  

It is clearly not a flag so code like this doesn't do what you expect:

#ifdef __BIG_ENDIAN__
//yada yada yada
#endif

The IEEE set of macros are flags, but they cannot be depended on to be
defined in spite of the comment in ieeefp.h:
   "Note that one of __IEEE_BIG_ENDIAN or __IEEE_LITTLE_ENDIAN must be
specified for a
   platform or error will occur."
It is easy to create a program where neither one is defined!

On my platform, which is Cygwin/Intel/x86/32bit, some of the numeric macros
are defined in usr/include/endian.h and usr/include/machine/endian.h and the
flags are defined in usr/include/machine/ieeefp.h.  Since these header files
define the correct answer for my platform I presume that they are
automatically generated during installation of the compiler as neither
header file appears as such in the build directory for a newly compiled GCC
(for c/c++).  From my own experiments the only reliable way to ensure that
some of the above macros are defined is to #include <endian.h>.  This header
is silently included in many other system files but not all of them. 

>From other correspondence I discover that the existance and location of
<endian.h> cannot be relied on across different platforms.

The recommended method to list all the predefined macros: 
  echo "" | gcc -E -dM -x c - | sort
doesn't list ANY of the above endian macros!

None of the above macro definitions appear in either the GCC or CPP manuals.
Although the GCC manual discusses many options for forcing the compiler to
generate code for various endianess, there is no discussion on how one
should test for it at compile time.

Questions:
1.  Since the compiler clearly HAS to know endianess why isn't there a
simple, robust way to test for it on all platforms without depending on a
header?

2.  How reliable is the existance of <endian.h> across all platforms?

3.  Which form of the many macro definitions of endianness should we be
using?  

4.  Why are these very basic platform constants NOT included in the -dM
output list?

5.  Where is the documentation on how one should write cross-platform code
wrt endianess using GCC?

Thanks,

Lee.









Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]