Re: bool and C23

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

 



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


[Index of Archives]     [GCC Help]     [Kernel Discussion]     [RPM Discussion]     [Red Hat Development]     [Yosemite News]     [Linux USB]     [Samba]

  Powered by Linux