Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Defining the __BYTE_ORDER__ macro - request for improvements

48 views
Skip to first unread message

Alf P. Steinbach

unread,
May 23, 2017, 12:07:31 PM5/23/17
to
Dear people! Folks! Y'all!

In some cases, e.g. when using g++'s `code_cvt` implementation, it's
necessary to know the host machine's byte order, a.k.a. endianness, at
compile time.

And I'd like that to not have a heavy 3rd party library dependency, such
as Boost.

The following is the best I've been able to come up with via simple
googling.

But, I don't have access to a lot of computers of different kinds. At
the moment I just have my old laptop. So it would be nice with some
scathing critique and/or constructive improvements, whatever! :)

-----------------------------------------------------------------------
#pragma once // Source encoding: utf-8 ∩
// #include <stdlib/workarounds/__BYTE_ORDER__.hpp>
//
// Copyright © 2017 Alf P. Steinbach, distributed under Boost license 1.0.

#ifndef __BYTE_ORDER__
# // The values used by the g++ compiler:
# define __ORDER_LITTLE_ENDIAN__ 1234
# define __ORDER_BIG_ENDIAN__ 4321
# define __ORDER_PDP_ENDIAN__ 3412
#
# if defined( _WIN32 )
# define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
# elif defined( __BIG_ENDIAN__ ) || defined( __BIG_ENDIAN ) ||
defined( _BIG_ENDIAN )
# define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
# elif defined( _ARCH_PPC ) || defined( __PPC__ ) || defined( __PPC )
|| defined( PPC ) \
|| defined( __powerpc__ ) || defined( __powerpc ) || defined(
powerpc )
# define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
# else
# error Please define __BYTE_ORDER__, e.g. as __LITTLE_ENDIAN__.
# endif
#endif
-----------------------------------------------------------------------

Source code DL: <url:
https://github.com/alf-p-steinbach/stdlib/blob/master/source/workarounds/__BYTE_ORDER__.hpp>.


Cheers!,

- Alf

Scott Lurndal

unread,
May 23, 2017, 12:15:35 PM5/23/17
to
"Alf P. Steinbach" <alf.p.stein...@gmail.com> writes:
>Dear people! Folks! Y'all!
>
>In some cases, e.g. when using g++'s `code_cvt` implementation, it's
>necessary to know the host machine's byte order, a.k.a. endianness, at
>compile time.
>

glibc has endian.h

which we use as follows (we don't need to run on Windows):

#include <endian.h>
#ifndef __BYTE_ORDER
#if defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
#define __BYTE_ORDER __BIG_ENDIAN
#elif !defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
#define __BYTE_ORDER __LITTLE_ENDIAN
#define __BIG_ENDIAN 4321
#elif !defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __BIG_ENDIAN
#else
#error Unable to determine Endian mode
#endif
#endif

#if !defined(htobe16)
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define htobe16(x) __bswap_16 (x)
# define htole16(x) (x)
# define be16toh(x) __bswap_16 (x)
# define le16toh(x) (x)

# define htobe32(x) __bswap_32 (x)
# define htole32(x) (x)
# define be32toh(x) __bswap_32 (x)
# define le32toh(x) (x)

# define htobe64(x) __bswap_64 (x)
# define htole64(x) (x)
# define be64toh(x) __bswap_64 (x)
# define le64toh(x) (x)
# else
# define htobe16(x) (x)
# define htole16(x) __bswap_16 (x)
# define be16toh(x) (x)
# define le16toh(x) __bswap_16 (x)

# define htobe32(x) (x)
# define htole32(x) __bswap_32 (x)
# define be32toh(x) (x)
# define le32toh(x) __bswap_32 (x)

# define htobe64(x) (x)
# define htole64(x) __bswap_64 (x)
# define be64toh(x) (x)
# define le64toh(x) __bswap_64 (x)
# endif
#endif

red floyd

unread,
May 23, 2017, 12:27:58 PM5/23/17
to
On 5/23/2017 9:15 AM, Scott Lurndal wrote:
> "Alf P. Steinbach" <alf.p.stein...@gmail.com> writes:
>> Dear people! Folks! Y'all!
>>
>> In some cases, e.g. when using g++'s `code_cvt` implementation, it's
>> necessary to know the host machine's byte order, a.k.a. endianness, at
>> compile time.
>>
>
> glibc has endian.h
>
> which we use as follows (we don't need to run on Windows):
>
> #include <endian.h>
> #ifndef __BYTE_ORDER
> #if defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
> #define __BYTE_ORDER __BIG_ENDIAN
> #elif !defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
> #define __BYTE_ORDER __LITTLE_ENDIAN
> #define __BIG_ENDIAN 4321
> #elif !defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
> #define __BIG_ENDIAN 4321
> #define __BYTE_ORDER __BIG_ENDIAN
> #else
> #error Unable to determine Endian mode
> #endif
> #endif
> [redacted]

And this example is illegal code, as it has a user-defined
identifier which is reserved to the implementation:

__BYTE_ORDER has two leading underscores. I was going to comment
on Alf's macro as well, but it appears to be a implementation header.
If it's his own file that he's placed in <stdlib/...>, then his code is
also illega.





Scott Lurndal

unread,
May 23, 2017, 12:42:12 PM5/23/17
to
Actually, it's preventive code in case the implementation doesn't
provide it when including <endian.h>, which has changed over the
last two decades such that there are versions of the file
that don't define __BYTE_ORDER and versions that do.

David Brown

unread,
May 23, 2017, 3:39:10 PM5/23/17
to
On 23/05/17 18:07, Alf P. Steinbach wrote:
> Dear people! Folks! Y'all!
>
> In some cases, e.g. when using g++'s `code_cvt` implementation, it's
> necessary to know the host machine's byte order, a.k.a. endianness, at
> compile time.
>
> And I'd like that to not have a heavy 3rd party library dependency, such
> as Boost.
>
> The following is the best I've been able to come up with via simple
> googling.
>
> But, I don't have access to a lot of computers of different kinds. At
> the moment I just have my old laptop. So it would be nice with some
> scathing critique and/or constructive improvements, whatever! :)
>

Many (not all) PowerPC processors can run in little endian mode as an
alternative to big endian. Most PPC compilers will, I think have
pre-defined symbols for endianness but they might not be gcc-style
__BYTE_ORDER__. Whether or not that is an issue will depend on the
target processors and compilers you expect to use.

I am curious - why do you specifically include the PPC, but not (for
example) MIPS or ARM ?

Alf P. Steinbach

unread,
Jun 6, 2017, 4:44:22 PM6/6/17
to
On 23-May-17 6:07 PM, Alf P. Steinbach wrote:
> Dear people! Folks! Y'all!
>
> In some cases, e.g. when using g++'s `code_cvt` implementation, it's
> necessary to know the host machine's byte order, a.k.a. endianness, at
> compile time.
>
> And I'd like that to not have a heavy 3rd party library dependency, such
> as Boost.

With the feedback I got on that original posting (thanks!) I've

• Changed the macro name from g++'s `__BYTE_ORDER__` to
`STDLIB_BYTE_ORDER`.
• Removed silly powerpc platform checking, for where would it end?

Is this reasonable then?


-----------------------------------------------------------------------------
#pragma once // Source encoding: utf-8 ∩
// #include <stdlib/workarounds/__BYTE_ORDER__.hpp>
//
// Copyright © 2017 Alf P. Steinbach, distributed under Boost license 1.0.

#ifdef __BYTE_ORDER__
# define STDLIB_BYTE_ORDER __BYTE_ORDER__
#
# if !( defined( __ORDER_LITTLE_ENDIAN__ ) && \
defined( __ORDER_BIG_ENDIAN__) && \
defined( __ORDER_PDP_ENDIAN__ ) )
# error __BYTE_ORDER__ is defined but one or more value macros are
missing.
# endif
#
# define STDLIB_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ // 1234
# define STDLIB_BIG_ENDIAN __ORDER_BIG_ENDIAN__ // 4321
# define STDLIB_MIXED_ENDIAN __ORDER_PDP_ENDIAN__ // 3412
#else
# // The values used by the g++ compiler:
# define STDLIB_LITTLE_ENDIAN 1234
# define STDLIB_BIG_ENDIAN 4321
# define STDLIB_MIXED_ENDIAN 3412
#
# if defined( _WIN32 )
# define STDLIB_BYTE_ORDER STDLIB_LITTLE_ENDIAN
# elif defined( __BIG_ENDIAN__ ) || defined( __BIG_ENDIAN ) ||
defined( _BIG_ENDIAN )
# define STDLIB_BYTE_ORDER STDLIB_BIG_ENDIAN
# else
# error Please define STDLIB_BYTE_ORDER, e.g. as STDLIB_LITTLE_ENDIAN.
# endif
#endif
-----------------------------------------------------------------------------


Cheers!,

- Alf


0 new messages