Albert Chin <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> * 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 > [EMAIL PROTECTED] + cp $(srcdir)/stdbool_.h [EMAIL PROTECTED] mv [EMAIL PROTECTED] $@ 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 <[EMAIL PROTECTED]>, 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 [EMAIL PROTECTED]@ -# 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])]) _______________________________________________ bug-gnulib mailing list bug-gnulib@gnu.org http://lists.gnu.org/mailman/listinfo/bug-gnulib