INN and the bool type

Russ Allbery rra at stanford.edu
Wed Jul 12 07:59:16 UTC 2000


Looks like ISO resolved this problem for us.

I haven't picked up the final ISO 9899:1999 standard (C99) yet because I'm
waiting for ANSI to have it available for $29 as a PDF rather than just
the ISO version for $249, but from the final committee draft (and I'm
fairly sure this has not changed between the draft and the final product),
section 6.2.5:

  2.  An object declared as type _Bool is large enough to store the values
      0 and 1.

and section 7.16:

  1.  The header <stdbool.h> defines four macros.

  2.  The macro

          bool

      expands to _Bool.

  3.  The remaining three macros are suitable for use in #if preprocessing
      directives.  They are

          true

      which expands to the decimal constant 1,

          false

      which expands to the decimal constant 0, and

          __bool_true_false_are_defined

      which expands to the decimal constant 1.

Accordingly, in a compliant C99 program, the standard way to use a Boolean
type is to include <stdbool.h> and then use bool as the type and true and
false as the constants.

I think we should therefore transition INN in that direction, under the
general principal of portable programming that says "program to the
standard and add hacks to make systems that don't support the standard
look like they do."  Accordingly, I've applied the following patch to
include/inn/defines.h to just include <stdbool.h> if built with a C99
compiler.

I think it's safe to use the preprocessor constant here rather than an
autoconf test; Boolean types are one of the easiest parts of C99 to get
right, and a compiler writer would have to get things *really* wrong to
have a compiler claiming it's C99-compliant and yet not have them.

Note that I'm not aware of any compiler which at this point claims to
comply with C99; gcc 2.95.1 doesn't (and doesn't provide a stdbool.h
that's compliant, although it does provide one which would work well
enough for INN's purposes).

Here's the patch.  All of the change after the #else is just indentation
changes in the preprocessor directives.

--- defines.h	2000/06/04 23:18:26	1.1
+++ defines.h	2000/07/12 07:58:14
@@ -43,35 +43,55 @@
 /* Used for unused parameters to silence gcc warnings. */
 #define UNUSED  __attribute__((__unused__))
 
-/* Make available the bool type.  The following macros were taken from the
-   Perl source, with some modifications. */
-#undef TRUE
-#undef FALSE
-#define TRUE    (1)
-#define FALSE   (0)
+/* Make available the bool type.  C99 requires that the bool type be made
+   available by including stdbool.h, as well as the true and false values,
+   so if we're in a C99 compilation environment, just include that header.
+   It would be nice to use an autoconf test, but as this is an installed
+   header, that would mean unnecessary additional complexity.  INN
+   internally uses TRUE and FALSE instead in a lot of places, so make them
+   available as well. */
+#if __STDC_VERSION__ >= 199901L
+# include <stdbool.h>
+# undef TRUE
+# undef FALSE
+# define TRUE   true
+# define FALSE  false
+
+#else
+
+/* We don't have stdbool.h, or can't rely on it, and therefore need to hack
+   something up ourselves.  These methods are taken from Perl with some
+   modifications. */
+
+# undef TRUE
+# undef FALSE
+# define TRUE   (1)
+# define FALSE  (0)
 
 /* C++ has a native bool type, and our TRUE and FALSE will work with it. */
-#ifdef __cplusplus
-# if !HAS_BOOL
-#  define HAS_BOOL 1
+# ifdef __cplusplus
+#  if !HAS_BOOL
+#   define HAS_BOOL 1
+#  endif
 # endif
-#endif
 
 /* The NeXT dynamic loader headers will not build with the bool macro, so
    use an enum instead (which appears to work). */
-#if !defined(HAS_BOOL) && (defined(NeXT) || defined(__NeXT__))
-# undef FALSE
-# undef TRUE
+# if !defined(HAS_BOOL) && (defined(NeXT) || defined(__NeXT__))
+#  undef FALSE
+#  undef TRUE
 typedef enum bool { FALSE = 0, TRUE = 1 } bool;
-# define ENUM_BOOL 1
+#  define ENUM_BOOL 1
+#  if !HAS_BOOL
+#   define HAS_BOOL 1
+#  endif
+# endif /* NeXT || __NeXT__ */
+
 # if !HAS_BOOL
+#  define bool int
 #  define HAS_BOOL 1
 # endif
-#endif /* NeXT || __NeXT__ */
 
-#if !HAS_BOOL
-# define bool int
-# define HAS_BOOL 1
-#endif
+#endif /* __STDC_VERSION__ < 199901L */
 
 #endif /* !INN_DEFINES_H */

-- 
Russ Allbery (rra at stanford.edu)             <http://www.eyrie.org/~eagle/>



More information about the inn-workers mailing list