From 03a8314d59f5cb0ec52073b34e14a6a108504a27 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 23 Apr 2017 20:54:35 -0700 Subject: [PATCH] Target a C99 subset, not a C89 subset For many years Gnulib has targeted C89 and has resisted using C99 features, as some Gnulib-using programs still wanted to target C89. As this no longer seems to be the case, relax the porting requirements to allow some C99 features. This is merely a change to the documentation, to give other Gnulib developers a chance to weigh in on the topic. * doc/extern-inline.texi (extern inline): * doc/gnulib-readme.texi (Portability guidelines): * doc/gnulib-tool.texi (Initial import): * doc/gnulib.texi (Header files): Modernize to talk about C99 and C11 instead of C89 and C99. * doc/gnulib-readme.texi (Portability guidelines): Now a section, not merely a subsection, so that it can be split up. Modernize a bit. (C language versions, C99 features assumed) (C99 features avoided): New sections. --- ChangeLog | 21 ++++++++ doc/extern-inline.texi | 10 ++-- doc/gnulib-readme.texi | 141 ++++++++++++++++++++++++++++++++++++++++--------- doc/gnulib-tool.texi | 4 +- doc/gnulib.texi | 2 +- 5 files changed, 146 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3f20b6..75e7d8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2017-04-23 Paul Eggert + + Target a C99 subset, not a C89 subset + For many years Gnulib has targeted C89 and has resisted using C99 + features, as some Gnulib-using programs still wanted to target + C89. As this no longer seems to be the case, relax the porting + requirements to allow some C99 features. This is merely a change + to the documentation, to give other Gnulib developers a chance to + weigh in on the topic. + * doc/extern-inline.texi (extern inline): + * doc/gnulib-readme.texi (Portability guidelines): + * doc/gnulib-tool.texi (Initial import): + * doc/gnulib.texi (Header files): + Modernize to talk about C99 and C11 instead of C89 and C99. + * doc/gnulib-readme.texi (Portability guidelines): + Now a section, not merely a subsection, so that it + can be split up. Modernize a bit. + (C language versions, C99 features assumed) + (C99 features avoided): + New sections. + 2017-04-23 Bruno Haible doc: New section "Modules that modify the way other modules work". diff --git a/doc/extern-inline.texi b/doc/extern-inline.texi index 60cfc0a..2494742 100644 --- a/doc/extern-inline.texi +++ b/doc/extern-inline.texi @@ -18,8 +18,8 @@ @cindex inline The @code{extern-inline} module supports the use of C99-style address@hidden inline} functions so that the code still runs on pre-C99 -compilers. address@hidden inline} functions so that the code still runs on +compilers that do not support this feature correctly. C code ordinarily should not use @code{inline}. Typically it is better to let the compiler figure out whether to inline, as compilers @@ -31,7 +31,7 @@ Functions defined (not merely declared) in headers are an exception, as avoiding @code{inline} would commonly cause problems for these functions. Suppose @file{aaa.h} defines the function @code{aaa_fun}, and @file{aaa.c}, @file{bbb.c} and @file{ccc.c} all include address@hidden If code is intended to portable to pre-C99 compilers, address@hidden If code is intended to portable to non-C99 compilers, @code{aaa_fun} cannot be declared with the C99 @code{inline} keyword. This problem cannot be worked around by making @code{aaa_fun} an ordinary function, as it would be defined three times with external @@ -77,8 +77,8 @@ whereas @file{bbb.c} and @file{ccc.c} can include @file{aaa.h} in the usual way. C99 compilers expand @code{AAA_INLINE} to C99-style @code{inline} usage, where @code{aaa_fun} is declared @code{extern inline} in @file{aaa.c} and plain @code{inline} in other modules. -Pre-C99 compilers that are compatible with GCC use GCC-specific syntax -to accomplish the same ends. Other pre-C99 compilers use @code{static +Non-C99 compilers that are compatible with GCC use GCC-specific syntax +to accomplish the same ends. Other non-C99 compilers use @code{static inline} so they suffer from code bloat, but they are not mainline platforms and will die out eventually. diff --git a/doc/gnulib-readme.texi b/doc/gnulib-readme.texi index 142143f..1422135 100644 --- a/doc/gnulib-readme.texi +++ b/doc/gnulib-readme.texi @@ -14,6 +14,7 @@ * Git Checkout:: * Keeping Up-to-date:: * Contributing to Gnulib:: +* Portability guidelines:: * High Quality:: @end menu @@ -124,7 +125,6 @@ you should probably consider packaging it as a separate library. * Gnulib licensing:: * Indent with spaces not TABs:: * How to add a new module:: -* Portability guidelines:: @end menu @node Gnulib licensing @@ -278,33 +278,54 @@ is not empty after preprocessing. One way to do this is to @end itemize @node Portability guidelines address@hidden Portability guidelines address@hidden Portability guidelines 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. +not just GNU platforms. Gnulib typically attempts to support a +platform as long as it is still supported by its provider, even if the +platform is not the latest version. @xref{Target Platforms}. Many Gnulib modules exist so that applications need not worry about undesirable variability in implementations. For example, an application that uses the @code{malloc} module need not worry about @code{malloc@ (0)} returning @code{NULL} on some Standard C -platforms; and @code{time_r} users need not worry about address@hidden returning @code{int} (not @code{char@ *}) on some -platforms that predate POSIX 1003.1-2001. - -Gnulib attempts to be portable to platforms that are still supported -by their providers, even if these systems are not the latest version. -Currently Gnulib assumes at least a freestanding C89 compiler, -possibly operating with a C library that predates C89; with time this +platforms; and @code{glob} users need not worry about @code{glob} +silently omitting symbolic links to nonexistent files on some +platforms that do not conform to POSIX. + +Gnulib code is intended to port without problem to new hosts, e.g., +hosts conforming to recent C and POSIX standards. Hence Gnulib code +should avoid using constructs that these newer standards no longer +require, without first testing for the presence of these constructs. +For example, because C11 made variable length arrays optional, Gnulib +code should avoid them unless it first uses the @code{vararrays} +module to check whether they are supported. + +The following subsections discuss some exceptions and caveats to the +general Gnulib portability guidelines. + address@hidden +* C language versions:: +* C99 features assumed:: +* C99 features avoided:: +* Other portability assumptions:: address@hidden menu + address@hidden C language versions address@hidden C language versions + +Currently Gnulib assumes at least a freestanding C99 compiler, +possibly operating with a C library that predates C99; with time this assumption will likely be strengthened to later versions of the C standard. Old platforms currently supported include AIX 6.1, HP-UX 11i v1 and Solaris 10, though these platforms are rarely tested. Gnulib itself is so old that it contains many fixes for obsolete platforms, fixes that may be removed in the future. -Because of the freestanding C89 assumption, Gnulib code can include address@hidden}, @code{}, @code{}, and address@hidden} unconditionally. It can also assume the existence +Because of the freestanding C99 assumption, Gnulib code can include address@hidden}, @code{}, @code{}, address@hidden}, @code{}, and @code{} +unconditionally. Gnulib code can also assume the existence of @code{}, @code{}, @code{}, @code{}, @code{}, @code{}, @code{}, @code{}, and @code{}. Similarly, @@ -314,7 +335,7 @@ forever. Even if the include files exist, they may not conform to the C standard. However, GCC has a @command{fixincludes} script that attempts to fix most -C89-conformance problems. So Gnulib currently assumes include files +C89-conformance problems. 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. @@ -324,6 +345,86 @@ You can work around some of these problems by requiring the relevant modules, e.g., the Gnulib @code{mktime} module supplies a working and conforming @code{mktime}. address@hidden C99 features assumed address@hidden C99 features assumed by Gnulib + +Although the C99 standard specifies many features, Gnulib code +is conservative about using them, partly because Gnulib predates +the widespread adoption of C99, and partly because many C99 +features are not well-supported in practice. C99 features that +are reasonably portable nowadays include: + address@hidden address@hidden +A declarations after a statement, or as the first clause in a address@hidden statement. + address@hidden address@hidden long int}. + address@hidden address@hidden}, assuming the @code{stdbool} module is used. address@hidden + address@hidden address@hidden}, assuming the @code{stdint} module is used. address@hidden + address@hidden +Compound literals and designated initializers. + address@hidden +Variadic macros. + address@hidden address@hidden inline} functions. + address@hidden address@hidden, assuming the @code{func} module is used. @xref{func}. + address@hidden +The @code{restrict} qualifier, assuming address@hidden([AC_C_RESTRICT])} is used. + address@hidden +Flexible array members (however, see the @code{flexmember} module). address@hidden itemize + address@hidden C99 features avoided address@hidden C99 features avoided by Gnulib + +Gnulib avoids some features even though they are standardized by C99, +as they have portability problems in practice. Here is a partial list +of avoided C99 features. Many other C99 features are portable only if +their corresponding modules are used; Gnulib code that uses such a +feature should require the corresponding module. + address@hidden address@hidden +Variable length arrays, unless @code{__STDC_NO_VLA__} is defined. +See the @code{vararrays} module. + address@hidden address@hidden inline} functions, without checking whether they are +supported. @xref{extern inline}. + address@hidden +Type-generic math functions. + address@hidden +Universal character names in source code. + address@hidden address@hidden}, since GNU programs need not worry about deficient +source-code encodings. + address@hidden +Comments beginning with @samp{//}. This is mostly for style reasons. address@hidden itemize + address@hidden Other portability assumptions address@hidden Other portability assumptions made by Gnulib + The GNU coding standards allow one departure from strict C: Gnulib code can assume that standard internal types like @code{size_t} are no wider than @code{long}. POSIX requires implementations to support at @@ -399,14 +500,6 @@ 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 recent C and POSIX standards. Hence -Gnulib code should avoid using constructs that these newer standards -no longer require, without first testing for the presence of these -constructs. For example, because C11 made variable length arrays -optional, Gnulib code should avoid them unless it first uses the address@hidden module to check whether they are supported. - @node High Quality @section High Quality diff --git a/doc/gnulib-tool.texi b/doc/gnulib-tool.texi index 2578fc8..d08aa44 100644 --- a/doc/gnulib-tool.texi +++ b/doc/gnulib-tool.texi @@ -100,7 +100,7 @@ Gnulib is used. Our example will be a library that uses Autoconf, Automake and Libtool. It calls @code{strdup}, and you wish to use gnulib to make -the package portable to C89 and C99 (which don't have @code{strdup}). +the package portable to C99 and C11 (which don't have @code{strdup}). @example ~/src/libfoo$ gnulib-tool --import strdup @@ -295,7 +295,7 @@ use of @code{strdup}. In the usual case where Autoconf is creating a @file{config.h} file, you should include @file{config.h} first, before any other include file. That way, for example, if @file{config.h} defines address@hidden to be the empty string on a pre-C99 host, or a macro address@hidden to be the empty string on a non-C99 host, or a macro like @samp{_FILE_OFFSET_BITS} that affects the layout of data structures, the definition is consistent for all include files. Also, on some platforms macros like @samp{_FILE_OFFSET_BITS} and diff --git a/doc/gnulib.texi b/doc/gnulib.texi index ea7710c..86e9f10 100644 --- a/doc/gnulib.texi +++ b/doc/gnulib.texi @@ -196,7 +196,7 @@ body of header file goes here @end example Whether to use @code{FOO_H} or @code{_FOO_H} is a matter of taste and -style. The C89 and C99 standards reserve all identifiers that begin with an +style. The C99 and C11 standards reserve all identifiers that begin with an underscore and either an uppercase letter or another underscore, for any use. Thus, in theory, an application might not safely assume that @code{_FOO_H} has not already been defined by a library. On the other -- 2.7.4