Austin Group Defect Tracker

Aardvark Mark III


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0000162 [1003.1(2008)/Issue 7] System Interfaces Comment Enhancement Request 2009-10-07 07:07 2013-05-16 16:38
Reporter Konrad_Schwarz View Status public  
Assigned To ajosey
Priority normal Resolution Accepted As Marked  
Status Resolved  
Name Konrad Schwarz
Organization Siemens AG
User Reference ntohs_endianess
Section ntohs
Page Number
Line Number
Interp Status ---
Final Accepted Text See Note: 0000665 and Note: 0001610
Summary 0000162: Determining System Endianess during Preprocessing
Description Sometimes one wants to compile conditionally depending on the endianess of the target platform. I am unaware of a portable (standard-based) way of determining endianess at preprocessing time.

However, a minor change to the definition of ntohs() and related functions would achieve this. The man page currently reads:

"On some implementations, these functions are defined as macros."

The BSD document "An Advanced 4.4BSD Interprocess Communication Tutorial" (http://docs.freebsd.org/44doc/psd/21.ipc/paper.pdf), [^] which introduced the ntohs() family of functions, states on page 15,

"On machines where unneeded these routines are defined as null macros."

I would like to have POSIX strengthened so that ntohs() etc. are macros exactly when the network byte order and host byte order are identical; that is, when the host is big-endian. The test for big-endianess could then be implemented as

# ifdef ntohs
/* big-endian specific code */
# else
/* non-big-endian, presumably little endian */
# endif

I realize that some machines, such as the PDP-11, are neither little nor big endian. However, such machines, similar to non-octet byte machines, are so rare that POSIX should not have to cater to them.

Note that it is not possible to implement ntohs() etc. on a little-endian machine using only a macro, as the byte swap must evaluate its argument several times. In standard C, a function is required.
Desired Action Change the sentence

"On some implementations, these functions are defined as macros."

to

"On exactly those implementations where network and host byte order are identical these functions are defined as macros."
Tags c99, issue8
Attached Files

- Relationships
related to 0000692Closed 1003.1(2013)/Issue7+TC1 More async-signal-safe functions 

-  Notes
(0000248)
eblake (manager)
2009-10-07 12:19

"Note that it is not possible to implement ntohs() etc. on a little-endian machine using only a macro" - not true. Yes, it is not possible to do so using strictly C99 constructs, but an implementation is free to use extensions as part of implementing a macro, and many implementations DO use a macro on little-endian machines that outputs an assembly directive for a byte swap while evaluating the argument exactly once. For example, on one little-endian system I sampled:

# define ntohs(x) \
(__builtin_constant_p((short)(x)) ? \
 __constant_ntohs((x)) : \
 __ntohs((x)))

where the semantics of __builtin_constant_p are such that side effects of x are not evaluated.

If we are to support endianness detection, it should by standardizing existing implementations, which provide a new header <endian.h> that defines either LITTLE_ENDIAN or BIG_ENDIAN as appropriate.
(0000250)
nick (manager)
2009-10-08 16:29

Forward this to the C99 committee for their consideration.
(0000279)
nick (manager)
2009-11-05 16:19

C99 is considering this, but have so far shown little enthusiasm. No formal proposal to add this has been made to the committee. Next April is the final chance to do so.
(0000312)
jpoehlmann (reporter)
2009-12-02 15:11

If this clause of the Standard would be fullfilled by most Unices, we could already base on it:

   The BSD document "An Advanced 4.4BSD Interprocess Communication
   Tutorial" (http://docs.freebsd.org/44doc/psd/21.ipc/paper.pdf), [^] [^] which
   introduced the ntohs() family of functions, states on page 15,
 
   "On machines where unneeded these routines are defined as null macros."

#ifdef ntohs
  #if ( ntohs ( 0x1234 ) == 0x1234 ) )
    #define BIGENDIAN_FOUND_AT_COMPILETIME = 1
  #endif
#else
  #define ENDIANNESS_UNKNONW_AT_COMPILETIME
#endif

This would also work in the case that ntohs is a macro
on a little endian platform.

Unfortunately on Linux (tested ppc and Intel) ntohs seems not to be a macro
so this test will mostly fail.

It may be preferable to standardize the __BYTE_ORDER, __BIG_ENDIAN and __LITTLE_ENDIAN macros found in glibc and some other UNICes.
(0000372)
Don Cragun (manager)
2010-01-07 17:06

This was discussed during today's conference call.
We do not believe that ntohs() should be required to be implemented in any particular way.

However, if the C Committee does not provide a way to determine endianness in the next revision of the C Standard, we will consider adding a new header and macros to specify implementation endianness for integral and floating point values.
(0000377)
drepper (reporter)
2010-01-21 16:12

The C committee hasn't shown enthusiasm to introduce macros for endianess handling. They are not opposed but somebody needs to do the work and preferably before the April C committee meeting.

If any of the people commenting here has interest, please provide a little paper describing the new feature with justification and changes to the spec. Either post it to the C committee mailing list directly or post it to the Austin Group mailing list and it will be appropriately forwarded.
(0000608)
nick (manager)
2010-11-05 14:38

No paper was submitted, so this issue is not being progressed in C.
(0000665)
nick (manager)
2011-02-03 18:15
edited on: 2011-03-03 16:59

Add the following to XBD in the correct alphabetic location (after
dlfcn.h, before errno.h):

<endian.h>

NAME
    endian.h - system endianness

SYNOPSIS
    #include <endian.h>

DESCRIPTION
    The <endian.h> header shall define at least the following macros
    for use in determining host byte order for integer types:

        BYTE_ORDER        this macro shall have a value equal to one
                          of the *_ENDIAN macros in this header.
        LITTLE_ENDIAN     if BYTE_ORDER == LITTLE_ENDIAN, the host
                          byte order is from least significant to
                          most significant.
        BIG_ENDIAN        if BYTE_ORDER == BIG_ENDIAN, the host byte
                          order is from most significant to least
                          significant.
    These macros shall be suitable for use in #if preprocessing directives.
    The macros BIG_ENDIAN and LITTLE_ENDIAN shall have distinct values.
    Implementations may define other macros with the _ENDIAN suffix.

    The following shall be declared as functions, or defined
    as macros, or both. If functions are declared, function prototypes
    shall be provided.

    uint16_t htobe16(uint16_t host_16bits);
    uint16_t htole16(uint16_t host_16bits);
    uint16_t be16toh(uint16_t big_endian_16bits);
    uint16_t le16toh(uint16_t little_endian_16bits);

    uint32_t htobe32(uint32_t host_32bits);
    uint32_t htole32(uint32_t host_32bits);
    uint32_t be32toh(uint32_t big_endian_32bits);
    uint32_t le32toh(uint32_t little_endian_32bits);

    uint64_t htobe64(uint64_t host_64bits);
    uint64_t htole64(uint64_t host_64bits);
    uint64_t be64toh(uint64_t big_endian_64bits);
    uint64_t le64toh(uint64_t little_endian_64bits);

    The <endian.h> header shall define the uint64_t, uint32_t and 
    uint16_t types as described in <stdint.h>.

    Inclusion of the <endian.h> header may also make visible all symbols
    from <stdint.h>.


APPLICATION_USAGE
    None

RATIONALE
    Many implementations also include PDP_ENDIAN to indicate a byte
    ordering where each pair of bytes is swapped. If BIG_ENDIAN is
    defined as 4321, PDP_ENDIAN would be 3412. However, this scheme
    is not universal, and derives its name from an obsolete processor.

FUTURE DIRECTION
    None.

SEE ALSO
    <stdint.h>
    XSH: htonl(), swab()

CHANGE HISTORY
    Added at Issue 8

===============================

Add a "Suffix" column to the table on P473. Change line 16039 to read:
"If any header in the following table is included,
macros with the prefixes or suffixes shown may be defined."

Add to the modified table on P473:
    Header        Prefix       Suffix
    <endian.h>                 _ENDIAN


===============================
Add a new page to XSH for be16toh(), and pointer pages for the other
functions listed here:

NAME
    be16toh, be32toh, be64toh, htobe16, htobe32, htobe64, 
    htole16, htole32, htole64, le16toh, le32toh, le64toh 

SYNOPSIS
    #include <endian.h>

    uint16_t htobe16(uint16_t host_16bits);
    uint16_t htole16(uint16_t host_16bits);
    uint16_t be16toh(uint16_t big_endian_16bits);
    uint16_t le16toh(uint16_t little_endian_16bits);

    uint32_t htobe32(uint32_t host_32bits);
    uint32_t htole32(uint32_t host_32bits);
    uint32_t be32toh(uint32_t big_endian_32bits);
    uint32_t le32toh(uint32_t little_endian_32bits);

    uint64_t htobe64(uint64_t host_64bits);
    uint64_t htole64(uint64_t host_64bits);
    uint64_t be64toh(uint64_t big_endian_64bits);
    uint64_t le64toh(uint64_t little_endian_64bits);

DESCRIPTION
    These functions convert integer values of various sizes between host
    representations and representations in a specified order.

    On some implementations, these functions are defined as macros.

    A little-endian representation of an integer has the least significant byte
    stored as the first byte, with the significance of the bytes increasing as the
    byte address increases. A big endian representation has the most significant
    byte as the first byte, with the significance of the bytes reducing as the byte
    address increases.

    NOTE: network byte order is "big-endian".

    For example, the uint32_t value 0x01020304 is represented as the four bytes
    0x04, 0x03, 0x02, 0x01 on a little endian host, and as 0x01, 0x02, 0x03, 0x04
    on a big endian host.

    For each of the sizes 16, 32 and 64, the htobeSIZE function shall convert from
    whatever order the host uses to big endian representation, htoleSIZE shall convert
    to little endian representation, beSIZEtoh shall convert from big endian to host
    order, and leSIZEtoh shall convert from little endian to host order.

RETURN VALUE
    These functions shall return an unsigned integer of the appropriate size and
    representation.

ERRORS
    No errors are defined.

EXAMPLES
    #include <endian.h>
    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, char *argv[])
    {
        uint32_t val;

        if (argc > 1) {
            val = (uint32_t)strtoul(argv[1], NULL, 0);
            printf("Value: %08x\n", val);

            printf("As bytes:\n");
            union {
                uint32_t asint;
                unsigned char asbytes[sizeof(uint32_t)];
            } u;
            printf("Little endian: ");
            u.asint = htole32(val);
            for (int i = 0; i < sizeof(uint32_t); i++) {
                printf("%02x ", u.asbytes[i]);
            }
            printf("\n");

            printf("Big endian   : ");
            u.asint = htobe32(val);
            for (int i = 0; i < sizeof(uint32_t); i++) {
                printf("%02x ", u.asbytes[i]);
            }
            printf("\n");
        }
        return 0;
    }

APPLICATION USAGE
    Since network order is defined as big endian, the following functions are equivalent
    if <arpa/inet.h> is included:

        <endian.h>        <arpa/inet.h>
        htobe32           htonl
        htobe16           htons
        be32toh           ntohl
        be16toh           ntohs

RATIONALE
    None

FUTURE DIRECTIONS
    None

SEE ALSO
    htonl()
    XBD <arpa/inet.h>

CHANGE HISTORY
    Added at Issue 8

Add to arpa/inet.h SEE ALSO page 222 line 7299:
    <endian.h>


Add to htonl, page 1097, line 36617:
    be16toh
and to line 36618:
    <endian.h>

(0001610)
eblake (manager)
2013-05-16 16:37

Additionally (per 0000692), add the following interfaces in sorted order to the table of async-signal-safe functions (page 494 of Issue7+TC1):
    be16toh, be32toh, be64toh, htobe16, htobe32, htobe64,
    htole16, htole32, htole64, le16toh, le32toh, le64toh

- Issue History
Date Modified Username Field Change
2009-10-07 07:07 Konrad_Schwarz New Issue
2009-10-07 07:07 Konrad_Schwarz Status New => Under Review
2009-10-07 07:07 Konrad_Schwarz Assigned To => ajosey
2009-10-07 07:07 Konrad_Schwarz Name => Konrad Schwarz
2009-10-07 07:07 Konrad_Schwarz Organization => Siemens AG
2009-10-07 07:07 Konrad_Schwarz User Reference => ntohs_endianess
2009-10-07 07:07 Konrad_Schwarz Section => ntohs
2009-10-07 12:19 eblake Note Added: 0000248
2009-10-08 16:28 nick Tag Attached: c99
2009-10-08 16:29 nick Note Added: 0000250
2009-11-05 16:19 nick Note Added: 0000279
2009-12-02 15:11 jpoehlmann Note Added: 0000312
2010-01-07 17:06 Don Cragun Note Added: 0000372
2010-01-21 16:12 drepper Note Added: 0000377
2010-11-05 14:38 nick Note Added: 0000608
2011-02-03 18:15 nick Note Added: 0000665
2011-02-03 18:20 nick Note Edited: 0000665
2011-02-17 18:40 nick Note Edited: 0000665
2011-02-17 18:41 nick Note Edited: 0000665
2011-03-03 16:24 nick Note Edited: 0000665
2011-03-03 16:26 nick Note Edited: 0000665
2011-03-03 16:28 nick Note Edited: 0000665
2011-03-03 16:34 nick Note Edited: 0000665
2011-03-03 16:34 nick Tag Attached: issue8
2011-03-03 16:35 nick Interp Status => ---
2011-03-03 16:35 nick Final Accepted Text => See Note: 0000665
2011-03-03 16:35 nick Status Under Review => Resolved
2011-03-03 16:35 nick Resolution Open => Accepted As Marked
2011-03-03 16:35 nick Note Edited: 0000665
2011-03-03 16:36 nick Note Edited: 0000665
2011-03-03 16:49 nick Note Edited: 0000665
2011-03-03 16:51 nick Note Edited: 0000665
2011-03-03 16:59 nick Note Edited: 0000665
2013-05-16 16:36 eblake Relationship added related to 0000692
2013-05-16 16:37 eblake Note Added: 0001610
2013-05-16 16:38 eblake Final Accepted Text See Note: 0000665 => See Note: 0000665 and Note: 0001610


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker