standards/188316: Visibility of ntohl etc. and POSIX 2008

Bruce Evans brde at
Sun Apr 6 17:50:01 UTC 2014

The following reply was made to PR standards/188316; it has been noted by GNATS.

From: Bruce Evans <brde at>
To: Christian Neukirchen <chneukirchen at>
Cc: freebsd-gnats-submit at, freebsd-standards at
Subject: Re: standards/188316: Visibility of ntohl etc. and POSIX 2008
Date: Mon, 7 Apr 2014 03:43:44 +1000 (EST)

 On Sun, 6 Apr 2014, Christian Neukirchen wrote:
 >> Description:
 > According to POSIX 2008, the functions ntohl etc. are defined in <arpa/inet.h> (, which works because they are defined unconditionally there.
 > However, just including <netinet/in.h> should also define them (
 >> The htonl(), htons(), ntohl(), and ntohs() functions shall be available
 >> as described in <arpa/inet.h>. Inclusion of the <netinet/in.h> header may
 >> also make visible all symbols from <arpa/inet.h>.
 POSIX.1-2001 also says this.
 > But ntohl etc are inside a "#if !defined(_KERNEL) && __BSD_VISIBLE" in <netinet/in.h>, violating the "shall be" requirement above.
 The requirement was somehow missed before.  Probably due to its bad wording.
 The bad wording "shall be available" is only used for namespaces twice in
 POSIX.1-2001-draft7 (for {h_errno} in <netdb.h> and for {ntoh*} in
 <netinet/in.h>.  The normal wording is "shall be defined as described in
 >> How-To-Repeat:
 > echo '#include <arpa/inet.h>\nint main(){htonl(1);}' | cc -D_XOPEN_SOURCE=700 -x c -
 > (all good)
 > echo '#include <netinet/in.h>\nint main(){htonl(1);}' | cc -D_XOPEN_SOURCE=700 -x c -
 > <stdin>:2:12: warning: implicit declaration of function 'htonl' is invalid in C99 [-Wimplicit-function-declaration]
 > int main(){htonl(1);}
 >           ^
 > 1 warning generated.
 >> Fix:
 > Guard the definition with __POSIX_VISIBLE >= 200112.
 This is wrong too, and is inconsistent with <arpa/inet.h> where there
 the symbols are defined unconditionally (if this wouldn't be redundant).
 The correctness of this depends on the symbols being in a header that
 doesn't exist in versions of POSIX that don't have the symbols.  I
 think it is indeed correct, because POSIX started specifying both the
 symbols and the headers in 2001.  Howver, the unconditional declarations
 may be wrong for XSI, and aren't really right for BSD.  In 4.4BSD, they
 were declared unconditionally in <sys/types.h> via nested pollution from
 <machine/endian.h>, and were only declared in the POSIX headers as a
 side effect of these headers being broken unless the application included
 <sys/types.h>.  Similarly in FreeBSD-1 (and Net/2?).  Applications written
 for this polluted API are no longer supported.  However, the documented
 API (byteorder.3) was that these functions are declared in <sys/param.h>.
 It is now that these functions are declared in the 2 POSIX headers.
 In the kernel, the ntoh* family is still declared in <sys/param.h>, but
 this is misdocumented in byteorder.9 which says that these functions
 are declared in <sys/endian.h>.  <sys/endian.h> actually declares almost
 all official endianness-related functions except these.  <sys/endian.h>
 and presumably all the functions of it are not documented in any application
 man page.
 mips still has bogus ntoh* functions in libc in asm.

More information about the freebsd-standards mailing list