Paul Eggert wrote on 2022-09-10: > I installed into Gnulib the stdbool patches ... > > After we have more experience with this in Gnulib, we can start thinking > about updating Autoconf. As part of this "gathering experience", I compiled a gnulib testdir with various compilers on various systems. No problems seen - with GCC, - with clang (I tested all versions from clang 3.9 to clang 14), - with AIX xlc and xlclang. But with Sun C++ on Solaris 10 (SOS11, __SUNPRO_CC=0x580 [1]) and 11.3 (solstudio12.2, __SUNPRO_CC=0x5110 [1]) I get a compilation error: CC -xarch=generic64 -O -DHAVE_CONFIG_H -DEXEEXT=\"\" -I. -I../../gltests -I.. -DGNULIB_STRICT_CHECKING=1 -DIN_GNULIB_TESTS=1 -I. -I../../gltests -I.. -I../../gltests/.. -I../gllib -I../../gltests/../gllib -I/home/haible/prefix-x86_64/include -D_REENTRANT -g -c -o test-stdbool-c++.o ../../gltests/test-stdbool-c++.cc "../../gltests/test-stdbool-c++.cc", line 33: Error: A declaration was expected instead of ""error: true is not 1"". 1 Error(s) detected. *** Error code 1 This compiler defines _BOOL, to indicate that 'bool', 'true', 'false' are keywords [2]. But in the preprocessor, 'true' evaluates to 0, not 1 ! Although cppreference.com does not clearly state that 'true' and 'false' must be usable as in preprocessor directives, such a compiler behaviour will show up as bugs in application programs, when more and more applications use 'true' and 'false' instead of old-style '1' and '0'. Thus, I think we should fix this compiler behaviour. What can the replacement be? #define true 1 does not work, because it would be of type 'int' and thus not behave right w.r.t. overloaded functions, such as int func (int); int func (bool); #define true ((bool) 1) fixes the type, but is not usable in preprocessor expressions, since casts are not allowed there. #define true (!false) works! It evaluates to 1 and is of the right type. Done through the attached patches. The second one should get included into Autoconf's AC_C_BOOL, when that comes to exist. [1] https://github.com/cpredef/predef/blob/master/Compilers.md [2] https://docs.oracle.com/cd/E37069_01/html/E54439/uc-cc-1.html 2022-09-18 Bruno Haible <bruno@xxxxxxxxx> stdbool: Ensure that 'true' can be used in the preprocessor. * m4/c-bool.m4 (gl_C_BOOL): With Sun C++, redefine 'true' if it does not evaluate to 1 in the preprocessor. stdbool-c99: Ensure that 'true' can be used in the preprocessor. * lib/stdbool.in.h (true): Redefine if it does not evaluate to 1 in the preprocessor.
>From e73f9ba6b3286e4cf570c77cd38f6ceff00653ba Mon Sep 17 00:00:00 2001 From: Bruno Haible <bruno@xxxxxxxxx> Date: Sun, 18 Sep 2022 18:45:39 +0200 Subject: [PATCH 1/2] stdbool-c99: Ensure that 'true' can be used in the preprocessor. * lib/stdbool.in.h (true): Redefine if it does not evaluate to 1 in the preprocessor. --- ChangeLog | 6 ++++++ lib/stdbool.in.h | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9b20b98d4a..3ea944f7d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-09-18 Bruno Haible <bruno@xxxxxxxxx> + + stdbool-c99: Ensure that 'true' can be used in the preprocessor. + * lib/stdbool.in.h (true): Redefine if it does not evaluate to 1 in the + preprocessor. + 2022-09-18 Bruno Haible <bruno@xxxxxxxxx> uni{case,ctype,gbrk,str}/base: Fix installed .h file (regr. 2022-09-10). diff --git a/lib/stdbool.in.h b/lib/stdbool.in.h index 36f26560af..834c5f7e78 100644 --- a/lib/stdbool.in.h +++ b/lib/stdbool.in.h @@ -109,6 +109,13 @@ typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool; # define false false # define true true # endif +/* In Sun C++ 5.11 (Solaris Studio 12.2) and older, 'true' as a preprocessor + expression evaluates to 0, not 1. Fix this by overriding 'true'. Note that + the replacement has to be of type 'bool'. */ +# if defined __SUNPRO_CC && true != 1 +# undef true +# define true (!false) +# endif #else # define false 0 # define true 1 -- 2.34.1
>From 16a1b6af1e618b22d621edc6054d4225cbcb98a1 Mon Sep 17 00:00:00 2001 From: Bruno Haible <bruno@xxxxxxxxx> Date: Sun, 18 Sep 2022 18:47:22 +0200 Subject: [PATCH 2/2] stdbool: Ensure that 'true' can be used in the preprocessor. * m4/c-bool.m4 (gl_C_BOOL): With Sun C++, redefine 'true' if it does not evaluate to 1 in the preprocessor. --- ChangeLog | 4 ++++ m4/c-bool.m4 | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ea944f7d2..87c370bd04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-09-18 Bruno Haible <bruno@xxxxxxxxx> + stdbool: Ensure that 'true' can be used in the preprocessor. + * m4/c-bool.m4 (gl_C_BOOL): With Sun C++, redefine 'true' if it does not + evaluate to 1 in the preprocessor. + stdbool-c99: Ensure that 'true' can be used in the preprocessor. * lib/stdbool.in.h (true): Redefine if it does not evaluate to 1 in the preprocessor. diff --git a/m4/c-bool.m4 b/m4/c-bool.m4 index db96ad1057..980de611b9 100644 --- a/m4/c-bool.m4 +++ b/m4/c-bool.m4 @@ -23,11 +23,21 @@ AC_DEFUN([gl_C_BOOL], fi dnl The "zz" puts this toward config.h's end, to avoid potential - dnl collisions with other definitions. Check - dnl __bool_true_false_are_defined to avoid re-including <stdbool.h>. + dnl collisions with other definitions. + dnl In C++ mode 'bool', 'true', 'false' are keywords and thus we don't need + dnl <stdbool.h>. But in C mode, we do. + dnl Check __bool_true_false_are_defined to avoid re-including <stdbool.h>. + dnl In Sun C++ 5.11 (Solaris Studio 12.2) and older, 'true' as a preprocessor + dnl expression evaluates to 0, not 1. Fix this by overriding 'true'. Note + dnl that the replacement has to be of type 'bool'. AH_VERBATIM([zzbool], -[#if (!defined HAVE_C_BOOL && !defined __cplusplus \ - && !defined __bool_true_false_are_defined) - #include <stdbool.h> +[#if !defined HAVE_C_BOOL +# if !defined __cplusplus && !defined __bool_true_false_are_defined +# include <stdbool.h> +# endif +# if defined __SUNPRO_CC && true != 1 +# undef true +# define true (!false) +# endif #endif]) ]) -- 2.34.1