Portable endianess

Discussion in 'C++' started by hantheman, Dec 20, 2003.

  1. hantheman

    hantheman Guest

    Is this a portable implementation?

    #if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)

    #define htons(A) (A)
    #define htonl(A) (A)
    #define ntohs(A) (A)
    #define ntohl(A) (A)

    #elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)

    #define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \
    (((uint16)(A) & 0x00ff) << 8))
    #define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
    (((uint32)(A) & 0x00ff0000) >> 8) | \
    (((uint32)(A) & 0x0000ff00) << 8) | \
    (((uint32)(A) & 0x000000ff) << 24))
    #define ntohs htons
    #define ntohl htohl

    #else

    #error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."

    #endif
     
    hantheman, Dec 20, 2003
    #1
    1. Advertising

  2. hantheman

    Jeff Schwab Guest

    hantheman wrote:
    > Is this a portable implementation?
    >
    > #if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
    >
    > #define htons(A) (A)
    > #define htonl(A) (A)
    > #define ntohs(A) (A)
    > #define ntohl(A) (A)
    >
    > #elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
    >
    > #define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \
    > (((uint16)(A) & 0x00ff) << 8))
    > #define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
    > (((uint32)(A) & 0x00ff0000) >> 8) | \
    > (((uint32)(A) & 0x0000ff00) << 8) | \
    > (((uint32)(A) & 0x000000ff) << 24))
    > #define ntohs htons
    > #define ntohl htohl
    >
    > #else
    >
    > #error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."
    >
    > #endif


    Who said bytes had eight bits?
     
    Jeff Schwab, Dec 20, 2003
    #2
    1. Advertising

  3. hantheman

    Heinz Ozwirk Guest

    "Jeff Schwab" <> schrieb im Newsbeitrag news:...
    : hantheman wrote:
    : > Is this a portable implementation?
    : >
    : > #if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
    : >
    : > #define htons(A) (A)
    : > #define htonl(A) (A)
    : > #define ntohs(A) (A)
    : > #define ntohl(A) (A)
    : >
    : > #elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
    : >
    : > #define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \
    : > (((uint16)(A) & 0x00ff) << 8))
    : > #define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
    : > (((uint32)(A) & 0x00ff0000) >> 8) | \
    : > (((uint32)(A) & 0x0000ff00) << 8) | \
    : > (((uint32)(A) & 0x000000ff) << 24))
    : > #define ntohs htons
    : > #define ntohl htohl
    : >
    : > #else
    : >
    : > #error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."
    : >
    : > #endif
    :
    : Who said bytes had eight bits?

    Who's talking about bytes? The 8 bits you probaly assume to be the number of bits in a (C++-) "byte" are the number of bits in a network octet, which is defined to be 8 bits.

    Heinz
     
    Heinz Ozwirk, Dec 21, 2003
    #3
  4. hantheman

    Jeff Schwab Guest

    Heinz Ozwirk wrote:
    > "Jeff Schwab" <> schrieb im Newsbeitrag news:...
    > : hantheman wrote:
    > : > Is this a portable implementation?
    > : >
    > : > #if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
    > : >
    > : > #define htons(A) (A)
    > : > #define htonl(A) (A)
    > : > #define ntohs(A) (A)
    > : > #define ntohl(A) (A)
    > : >
    > : > #elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
    > : >
    > : > #define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \
    > : > (((uint16)(A) & 0x00ff) << 8))
    > : > #define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
    > : > (((uint32)(A) & 0x00ff0000) >> 8) | \
    > : > (((uint32)(A) & 0x0000ff00) << 8) | \
    > : > (((uint32)(A) & 0x000000ff) << 24))
    > : > #define ntohs htons
    > : > #define ntohl htohl
    > : >
    > : > #else
    > : >
    > : > #error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."
    > : >
    > : > #endif
    > :
    > : Who said bytes had eight bits?
    >
    > Who's talking about bytes? The 8 bits you probaly assume to be the number of bits in a (C++-) "byte" are the number of bits in a network octet, which is defined to be 8 bits.
    >
    > Heinz



    Thanks for clarifying. :) Poor assumption on my part.

    Another question: Why are you doing all this in the preprocessor?
     
    Jeff Schwab, Dec 21, 2003
    #4
  5. On Sun, 21 Dec 2003 11:51:46 +0100, "Heinz Ozwirk" <>
    wrote:

    >"Jeff Schwab" <> schrieb im Newsbeitrag news:...
    >: hantheman wrote:
    >: > Is this a portable implementation?


    #include <winsock.h>
    and
    #include <winsock2.h>
    are. Unless you are implementing Winsock, you should use your
    system's header.

    [snip]

    Sincerely,

    Gene Wirchenko
     
    Gene Wirchenko, Dec 22, 2003
    #5
  6. Jeff Schwab wrote:
    > hantheman wrote:
    >
    >> Is this a portable implementation?
    >>
    >> #if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)

    <snip>

    Only if you can rely on the programmer's knowing which endianness
    his/her platform is.

    Moreover, there might not even be a programmer, but merely someone who's
    compiling a program delivered in source form.

    I recently did something with this. Basically, I was modifying rayshade
    to generate BMP output. I don't have the code over here, but it was
    something like:

    union EndianBytes {
    unsigned char b[4];
    short s;
    long l;
    }

    short LEShort(short s) {
    EndianBytes e;

    e.b[0] = (unsigned char) s;
    e.b[1] = (unsigned char) (s >> 8);

    return e.s;
    }

    LEShort converts a short from platform byte-order to little-endian or
    vice versa. It's straightforward to write BEShort, LELong and BELong on
    the same principle.

    Of course it still relies on some standard dimensions (byte = 8 bits,
    short = 2 bytes, long = 4 bytes), but it'll work on either BE or LE
    platforms without requiring any extra attention or knowledge on the side
    of the person writing/compiling a program that uses it.

    Stewart.

    --
    My e-mail is valid but not my primary mailbox. Please keep replies on
    on the 'group where everyone may benefit.
     
    Stewart Gordon, Dec 27, 2003
    #6
  7. "Stewart Gordon" <> wrote in message
    news:3fee0936@212.67.96.135...
    > Jeff Schwab wrote:
    > > hantheman wrote:
    > >
    > >> Is this a portable implementation?
    > >>
    > >> #if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)

    > <snip>
    >
    > Only if you can rely on the programmer's knowing which endianness
    > his/her platform is.
    >


    I've recently been using QNX and they have a very clean and logical way of
    pushing the endianness issue into 'the implementation':

    They just provide macros such as ENDIAN_BE16(x), ENDIAN_LE16(x),
    ENDIAN_BE32(x) etc..
    If you are dealing with an external format that you know to be Bigendian 16
    bits then whenever you read it in you convert it with
    internal_format = ENDIAN_BE16(external_format) and when you want to send it
    out you use
    external_format = ENDIAN_BE16(internal_format)

    The implementation conditionally compiles the macros to be either a byte
    swap or no op depending on the endianness of the system.

    Obviously this doesn't actually answer the question of how to determine the
    endianness of a system (which cannot portably be done at compile time) but
    is a very clean way of keeping all (host) endianness issues hidden away in
    one header file and concentrates instead on interface endianness which is as
    it should be.
     
    Nick Hounsome, Dec 28, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Endianess...

    , Feb 2, 2005, in forum: C++
    Replies:
    4
    Views:
    482
    Howard
    Feb 3, 2005
  2. SpOiLeR
    Replies:
    5
    Views:
    1,348
    SpOiLeR
    Mar 16, 2005
  3. Guest

    endianess

    Guest, Jul 18, 2003, in forum: C Programming
    Replies:
    8
    Views:
    668
    Kevin Easton
    Jul 20, 2003
  4. Oliver Knoll
    Replies:
    12
    Views:
    435
    RoSsIaCrIiLoIA
    Sep 16, 2004
  5. jlara

    Checking endianess in compile time

    jlara, Jun 6, 2005, in forum: C Programming
    Replies:
    7
    Views:
    383
    Michael Mair
    Jun 7, 2005
Loading...

Share This Page