Gnulib code is intended to be portable to a wide variety of platforms, not just GNU platforms. See the documentation section “Target Platforms” for details.
Many Gnulib modules exist so that applications need not worry about
undesirable variability in implementations. For example, an
application that uses the malloc module need not worry about
malloc (0) returning NULL on some Standard C
platforms; and time_r users need not worry about
localtime_r returning int (not char *) on some
platforms that predate POSIX 1003.1-2001.
Currently we assume at least a freestanding C89 compiler, possibly operating with a C library that predates C89. The oldest environments currently ported to are probably HP-UX 10.20 and IRIX 5.3, though we are not testing these platforms very often.
Because we assume a freestanding C89 compiler, Gnulib code can include
<float.h>, <limits.h>, <stdarg.h>, and
<stddef.h> unconditionally. It can also assume the existence
of <ctype.h>, <errno.h>, <fcntl.h>,
<locale.h>, <signal.h>, <stdio.h>,
<stdlib.h>, <string.h>, and <time.h>. Similarly,
many modules include <sys/types.h> even though it's not even in
C99; that's OK since <sys/types.h> has been around nearly
forever.
Even if the include files exist, they may not conform to C89. However, GCC has a fixincludes script that attempts to fix most C89-conformance problems. So Gnulib currently assumes include files largely conform to C89 or better. People still using ancient hosts should use fixincludes or fix their include files manually.
Even if the include files conform to C89, the library itself may not.
For example, strtod and mktime have some bugs on some platforms.
You can work around some of these problems by requiring the relevant
modules, e.g., the Gnulib mktime module supplies a working and
conforming mktime.
The GNU coding standards allow one departure from strict C99: Gnulib
code can assume that standard internal types like size_t are no wider
than long. POSIX 1003.1-2001 and the GNU coding standards both
require int to be at least 32 bits wide, so Gnulib code assumes this
as well. Gnulib code makes the following additional assumptions:
Previously, Gnulib code sometimes assumed that signed integer arithmetic wraps around, but modern compiler optimizations sometimes do not guarantee this, and Gnulib code with this assumption is now considered to be questionable. See Integer Properties.
Some Gnulib modules contain explicit support for the other signed integer representations allowed by C99 (ones' complement and signed magnitude), but these modules are the exception rather than the rule. All practical Gnulib targets use two's complement.
size_t values, then S + T cannot overflow.
(char *) &O <= (char *) P && (char *) P <
(char *) (&O + 1).
+ T cannot overflow.
Overflow in this case would mean that the rest of your program fits
into T bytes, which can't happen in realistic flat-address-space
hosts.
memset (A, 0, sizeof A) initializes an array A of
pointers to NULL.
0 + (char *) NULL == (char *) NULL.
The above assumptions are not required by the C or POSIX standards but hold on all practical porting targets that we're familiar with. If you have a porting target where these assumptions are not true, we'd appreciate hearing of any fixes. We need fixes that do not increase runtime overhead on standard hosts and that are relatively easy to maintain.
With the above caveats, Gnulib code should port without problem to new
hosts, e.g., hosts conforming to C99 or to recent POSIX standards.
Hence Gnulib code should avoid using constructs (e.g., undeclared
functions return int) that do not conform to C99.