bug-gnulib
[Top][All Lists]
Advanced

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

Re: proposed stdbool fixes for AIX, HP-UX, and now IRIX


From: Paul Eggert
Subject: Re: proposed stdbool fixes for AIX, HP-UX, and now IRIX
Date: Wed, 25 Jan 2006 10:56:57 -0800
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

Bruno Haible <address@hidden> writes:

>   - "enum" is fundamentally the right concept for this; "enum" in C was
>     introduced for exactly this kind of symbolic values,

Quite true, and we should use it when we know that it works.

>   - We have already invested some effort
>     in these modules. I'm not interested in retesting it

Yes, and that's why I'm proposing these changes.  We have run into
problems when using gnulib stdbool with coreutils and bison (and tar
too, if memory serves).  The patched stdbool works.  It works mainly
because it is more conservative than what is in gnulib -- it does not
use a feature unless we are sure that it works.  I'd rather not spend
time worrying about whether we will run into problems with enum values
with older, nonstandard compilers of unknown vintage, and having to
modify stdbool_.h every time we run into another one.

How about this change?  It reflects what's currently installed into
coreutils (I merged your changes).  I've tested this with GCC 2.95 and
it works the way you like there.  The basic idea is to make bool an
enum type when using GCC, but to fall back on signed char
otherwise.  This simplifies stdbool_.h and makes it more conservative.
The ChangeLog entry has the most-complicated conditional I've ever
written inside [brackets], but that complication is there precisely
because the proposed patch removes it from the code.

Also, this patch fixes a bug on HP-UX.
<http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html>
indicates why the "*pq |= q" business is necessary.  And I have added
a comment explaining why the "__GNUC__" part is useful.


2006-01-25  Paul Eggert  <address@hidden>

        Merge from coreutils.
        * lib/stdbool_.h (_Bool)
        [(! (defined __cplusplus || defined __BEOS__)
          && ((@HAVE__BOOL@ && ! (defined __HP_cc || defined __xlc__))
              || ! ((defined __SUNPRO_C
                     && (__SUNPRO_C < 0x550 || __STDC__ == 1))
                    || (defined __sgi && !defined __GNUC__))))]:
        #define to signed char in these cases too; this simplifies
        the code (so that we don't have to worry about HP-UX, AIX, SunPRO,
        etc., separately) and makes it more conservative.
        * m4/stdbool.m4 (AC_HEADER_STDBOOL): Check for xlc bug if __GCC__ too,
        so that we test the test.
        Check for yet another HP-UX bug involving *bool |= bool.

*** gnulib/lib/stdbool_.h       Wed Jan 25 09:57:43 2006
--- cu-ldd/lib/stdbool_.h       Wed Jan 25 10:17:36 2006
***************
*** 69,75 ****
     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__
    /* A compiler known to have 'bool'.  */
    /* If the compiler already has both 'bool' and '_Bool', we can assume they
--- 69,82 ----
     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'.  This works
!    with older GCC versions that do not have a working <stdbool.h>,
!    and it makes bool easier to to debug, so we use this with GCC.
! 
!    This approach into problems on some non-GCC platforms; the simplest
!    way to work around them is to ignore any existing definition of
!    _Bool and use our own.  */
! 
  #if defined __cplusplus || defined __BEOS__
    /* A compiler known to have 'bool'.  */
    /* If the compiler already has both 'bool' and '_Bool', we can assume they
***************
*** 78,105 ****
  typedef bool _Bool;
  # endif
  #else
! # if @HAVE__BOOL@
! #  if defined __HP_cc || defined __xlc__
      /* Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when
         the built-in _Bool type is used.  See
           http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
           http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
           http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
!        Override it.  */
! #   define _Bool signed char
! enum { false = 0, true = 1 };
! #  endif
! # else
! #  if (defined __SUNPRO_C && (__SUNPRO_C < 0x550 || __STDC__ == 1)) || 
(defined __sgi && !defined __GNUC__)
!     /* With SunPRO C, avoid stupid
           "warning: _Bool is a keyword in ISO C99".
         With IRIX cc, avoid stupid
!          "warning(1185): enumerated type mixed with another type".  */
! #   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
  #endif
  #define bool _Bool
--- 85,111 ----
  typedef bool _Bool;
  # endif
  #else
! # if @HAVE__BOOL@ || ! defined __GNUC__
!     /* The compiler has _Bool, or it is not GCC.  Recall that this
!        code is used only if <stdbool.h> does not work, so something is
!        odd if there is a _Bool.  */
! 
      /* Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when
         the built-in _Bool type is used.  See
           http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
           http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
           http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
!        With SunPRO C, avoid stupid
           "warning: _Bool is a keyword in ISO C99".
         With IRIX cc, avoid stupid
!          "warning(1185): enumerated type mixed with another type".
!        In general, there are enough problems with older compilers like
!        this that it's safer to avoid their _Bool entirely when
!        <stdbool.h> doesn't work.  */
! #  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
  #define bool _Bool
*** gnulib/m4/stdbool.m4        Tue Jan 24 16:15:38 2006
--- cu-ldd/m4/stdbool.m4        Tue Jan 24 22:18:34 2006
*************** AC_DEFUN([AC_HEADER_STDBOOL],
*** 74,80 ****
          _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__
           /* 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
--- 74,80 ----
          _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
*************** AC_DEFUN([AC_HEADER_STDBOOL],
*** 86,92 ****
              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
--- 86,95 ----
              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.  We also test
!             this with GCC, where it should work, to detect more
!             quickly whether someone messes up the test in the
!             future.  */
           char digs[] = "0123456789";
           int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1);
          #endif
*************** AC_DEFUN([AC_HEADER_STDBOOL],
*** 98,106 ****
          _Bool *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);
        ],
        [ac_cv_header_stdbool_h=yes],
        [ac_cv_header_stdbool_h=no])])
--- 101,111 ----
          _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 + !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]