bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: lib/stdbool_.h doesn't honor HAVE__BOOL


From: Paul Eggert
Subject: Re: lib/stdbool_.h doesn't honor HAVE__BOOL
Date: Fri, 25 Nov 2005 23:11:05 -0800
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

Albert Chin <address@hidden> writes:

> The HP-UX 11.23/IA aCC6 compiler has bool and _Bool. This generates an
> error building something that includes gnulib's auto-generated stdbool.h:

Unfortunately that isn't enough to fix the stdbool module problems
we've been running into recently with coreutils.  They include:

Some HP-UX C compilers mishandle _Bool (internal compiler error),
independently of whether <stdbool.h> works.  E.g.,
<http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html>,
<http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html>.

IBM C compiler mishandles sign-extension when combining _Bool with int.  E.g.,
<http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html>.

Some of the complexity of stdbool_.h is due to the desire to debug
bool variables nicely with GDB, when you are using an older compiler
that doesn't have a working <stdbool.h>.  That motivation is becoming
more and more obsolescent these days, though, since most developers
these days use compilers that support <stdbool.h>.  So I propose that
we drop this as a goal for stdbool_.h.  This allows us to simplify the
file quite a bit, and fix the above bugs.  Here is a proposed patch,
which I've installed into coreutils (but not gnulib).

2005-11-25  Paul Eggert  <address@hidden>

        * modules/stdbool (Makefile.am): Don't edit @HAVE__BOOL@; no longer
        needed.
        * lib/stdbool_.h: Simplify greatly, under the assumption that these
        days most people use C99-compatible compilers to debug, so it's
        not worth worrying about catering to older compilers for that.
        This works around some porting problems with HP-UX compilers.
        (false, true) [defined __BEOS__]: Don't #undef; no longer needed.
        (_Bool): typedef to bool if C++ or BeOS, and #define to signed char
        otherwise.
        * m4/stdbool.m4 (AM_STDBOOL_H): Don't bother substituting HAVE__BOOL;
        no longer needed.
        (AC_HEADER_STDBOOL): Check for IBM and HP-UX bugs.

Index: modules/stdbool
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/stdbool,v
retrieving revision 1.11
diff -p -u -r1.11 stdbool
--- modules/stdbool     22 Jul 2005 22:04:12 -0000      1.11
+++ modules/stdbool     26 Nov 2005 07:02:39 -0000
@@ -18,7 +18,7 @@ EXTRA_DIST += stdbool_.h
 # We need the following in order to create <stdbool.h> when the system
 # doesn't have one that works.
 stdbool.h: stdbool_.h
-       sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool_.h > 
address@hidden
+       cp $(srcdir)/stdbool_.h address@hidden
        mv address@hidden $@
 MOSTLYCLEANFILES += stdbool.h stdbool.h-t
 
Index: lib/stdbool_.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/stdbool_.h,v
retrieving revision 1.6
diff -p -u -r1.6 stdbool_.h
--- lib/stdbool_.h      14 May 2005 06:03:58 -0000      1.6
+++ lib/stdbool_.h      26 Nov 2005 07:02:40 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
    Written by Bruno Haible <address@hidden>, 2001.
 
    This program is free software; you can redistribute it and/or modify
@@ -54,35 +54,45 @@
 /* 7.16. Boolean type and values */
 
 /* BeOS <sys/socket.h> already #defines false 0, true 1.  We use the same
-   definitions below, but temporarily we have to #undef them.  */
+   definitions below, which is OK.  */
 #ifdef __BEOS__
 # include <OS.h> /* defines bool but not _Bool */
-# undef false
-# undef true
 #endif
 
-/* For the sake of symbolic names in gdb, we define true and false as
-   enum constants, not only as macros.
-   It is tempting to write
-      typedef enum { false = 0, true = 1 } _Bool;
-   so that gdb prints values of type 'bool' symbolically. But if we do
+/* C++ and BeOS have a reliable _Bool.  Otherwise, since this file is
+   being compiled, the system <stdbool.h> is not reliable so assume
+   that the system _Bool is not reliable either.  Under that
+   assumption, it is tempting to write
+
+      typedef enum { false, true } _Bool;
+
+   so that gdb prints values of type 'bool' symbolically.  But if we do
    this, values of type '_Bool' may promote to 'int' or 'unsigned int'
    (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int'
-   (see ISO C 99 6.3.1.1.(2)).  So we add a negative value to the
-   enum; this ensures that '_Bool' promotes to 'int'.  */
-#if !(defined __cplusplus || defined __BEOS__)
-# if address@hidden@
-#  if defined __SUNPRO_C && (__SUNPRO_C < 0x550 || __STDC__ == 1)
-    /* Avoid stupid "warning: _Bool is a keyword in ISO C99".  */
-#   define _Bool signed char
-enum { false = 0, true = 1 };
-#  else
-typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
-#  endif
-# endif
-#else
+   (see ISO C 99 6.3.1.1.(2)).  We could instead try this:
+
+      typedef enum { _Bool_dummy = -1, false, true } _Bool;
+
+   as the negative value ensures that '_Bool' promotes to 'int'.
+   However, this runs into some other problems.  First, Sun's C
+   compiler when (__SUNPRO_C < 0x550 || __STDC__ == 1) issues a stupid
+   "warning: _Bool is a keyword in ISO C99".  Second, IBM's AIX cc
+   compiler 6.0.0.0 (and presumably other versions) mishandles
+   subscripts involving _Bool (effectively, _Bool promotes to unsigned
+   int in this case), and we need to redefine _Bool in that case.
+   Third, HP-UX 10.20's C compiler lacks <stdbool.h> but has _Bool and
+   mishandles comparisons of _Bool to int (it promotes _Bool to
+   unsigned int).
+
+   The simplest way to work around these problems is to ignore any
+   existing definition of _Bool and use our own.  */
+
+#if defined __cplusplus || defined __BEOS__
 typedef bool _Bool;
+#else
+# define _Bool signed char
 #endif
+
 #define bool _Bool
 
 /* The other macros must be usable in preprocessor directives.  */
Index: m4/stdbool.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/stdbool.m4,v
retrieving revision 1.8
diff -p -u -r1.8 stdbool.m4
--- m4/stdbool.m4       17 Oct 2005 18:06:51 -0000      1.8
+++ m4/stdbool.m4       26 Nov 2005 07:02:40 -0000
@@ -11,7 +11,7 @@ AC_DEFUN([AM_STDBOOL_H],
 [
   AC_REQUIRE([AC_HEADER_STDBOOL])
 
-  # Define two additional variables used in the Makefile substitution.
+  # Define an additional variable used in the Makefile substitution.
 
   if test "$ac_cv_header_stdbool_h" = yes; then
     STDBOOL_H=''
@@ -19,13 +19,6 @@ AC_DEFUN([AM_STDBOOL_H],
     STDBOOL_H='stdbool.h'
   fi
   AC_SUBST([STDBOOL_H])
-
-  if test "$ac_cv_type__Bool" = yes; then
-    HAVE__BOOL=1
-  else
-    HAVE__BOOL=0
-  fi
-  AC_SUBST([HAVE__BOOL])
 ])
 
 # AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future.
@@ -74,11 +67,31 @@ AC_DEFUN([AC_HEADER_STDBOOL],
          _Bool n[m];
          char o[sizeof n == m * sizeof n[0] ? 1 : -1];
          char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+         #if defined __xlc__ || __GNUC__
+          /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0
+             reported by James Lemley on 2005-10-05; see
+             
<http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html>.
+             This test is not quite right, since xlc is allowed to
+             reject this program, as the initializer for xlcbug is
+             not one of the forms that C requires support for.
+             However, doing the test right would require a run-time
+             test, and that would make cross-compilation harder.
+             Let us hope that IBM fixes the xlc bug, and also adds
+             support for this kind of constant expression.  In the
+             meantime, this test will reject xlc, which is OK, since
+             our stdbool.h substitute should suffice.  */
+          char digs[] = "0123456789";
+          int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1);
+         #endif
+         _Bool q = true;
+         _Bool *pq = &q;
        ],
        [
+         *pq |= q;
+         *pq |= ! q;
          /* Refer to every declared value, to avoid compiler optimizations.  */
          return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
-                 + !m + !n + !o + !p);
+                 + !m + !n + !o + !p + !q + !pq);
        ],
        [ac_cv_header_stdbool_h=yes],
        [ac_cv_header_stdbool_h=no])])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]