This is the mail archive of the
mailing list for the GCC project.
Robust detection of endianness at compile time.
- From: "Lee Rhodes" <lee at rhoba dot com>
- To: <gcc-help at gcc dot gnu dot org>
- Date: Sun, 29 Jul 2007 02:15:24 -0700
- Subject: 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:
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>
There appear to be 3 types of endianess: Big (=network), Little, and
If the numeric variables are to be trusted the way to test for endianness
would be something like this:
#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...
#error "Endian determination failed"
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:
//yada yada yada
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.
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
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
4. Why are these very basic platform constants NOT included in the -dM
5. Where is the documentation on how one should write cross-platform code
wrt endianess using GCC?