bool and C23

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

 



I installed the attached patch into Gnulib, reflecting a patch I recently installed into Autoconf <https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=6dcecb780a69bd208088d666b299e92aa7ae7e80>.

I think we need a new Autoconf macro that obsoletes AC_HEADER_STDBOOL and AC_CHECK_HEADER_STDBOOL. This new macro should arrange for 'bool', 'true' and 'false' to work, without programs having to include stdbool.h. For C23 and C++ the new macro should do nothing. For C99 through C17 it should include <stdbool.h> in config.h. For pre-C99 it should #define bool, true, and false in config.h.

Eventually Gnulib and other code can stop using AC_*HEADER_CHECKBOOL and stop including <stdbool.h>.

I'm thinking of calling the new macro AC_C_BOOL. Gnulib can have a new c-bool module that implements AC_C_BOOL for platforms running older Autoconf.

Comments?
From f960bc91cd325cee7e1262944ca6114bfd4d1c1f Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@xxxxxxxxxxx>
Date: Sat, 13 Aug 2022 20:00:02 -0700
Subject: [PATCH] stdbool: port to C23
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* m4/stdbool.m4 (AC_CHECK_HEADER_STDBOOL): Copy from bleeding-edge
Autoconf.  Don’t define if Autoconf 2.72 or later.
* tests/test-stdbool.c (bool, false, true)
(__bool_true_false_are_defined): Do not require these to be
defined.  C23 still requires __bool_true_false_are_defined but
marks it as obsolescent, and it’s no longer worth testing.
(WORKING_BOOL): New macro, which also tests __STDC_VERSION__.
Use it in tests for working bool.
Test for bool instead of for _Bool, which C23 says is obsolescent.
---
 ChangeLog            |  13 ++++++
 m4/stdbool.m4        | 105 ++++++++++++++++++++++---------------------
 tests/test-stdbool.c |  41 ++++++++---------
 3 files changed, 84 insertions(+), 75 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e0bf24fc90..eecf44ba01 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2022-08-13  Paul Eggert  <eggert@xxxxxxxxxxx>
+
+	stdbool: port to C23
+	* m4/stdbool.m4 (AC_CHECK_HEADER_STDBOOL): Copy from bleeding-edge
+	Autoconf.  Don’t define if Autoconf 2.72 or later.
+	* tests/test-stdbool.c (bool, false, true)
+	(__bool_true_false_are_defined): Do not require these to be
+	defined.  C23 still requires __bool_true_false_are_defined but
+	marks it as obsolescent, and it’s no longer worth testing.
+	(WORKING_BOOL): New macro, which also tests __STDC_VERSION__.
+	Use it in tests for working bool.
+	Test for bool instead of for _Bool, which C23 says is obsolescent.
+
 2022-08-13  Bruno Haible  <bruno@xxxxxxxxx>
 
 	gnulib-tool.py: Fix some code generation details.
diff --git a/m4/stdbool.m4 b/m4/stdbool.m4
index 3e6c400546..c67908aa87 100644
--- a/m4/stdbool.m4
+++ b/m4/stdbool.m4
@@ -43,75 +43,76 @@ AC_DEFUN([gl_STDBOOL_H],
   AC_SUBST([HAVE__BOOL])
 ])
 
-# This version of the macro is needed in autoconf <= 2.68.
+m4_version_prereq([2.72], [], [
 
 AC_DEFUN([AC_CHECK_HEADER_STDBOOL],
-  [AC_CACHE_CHECK([for stdbool.h that conforms to C99],
+  [AC_CHECK_TYPES([_Bool])
+   AC_CACHE_CHECK([for stdbool.h that conforms to C99 or later],
      [ac_cv_header_stdbool_h],
      [AC_COMPILE_IFELSE(
         [AC_LANG_PROGRAM(
-           [[
-             #include <stdbool.h>
-
-             #ifdef __cplusplus
-              typedef bool Bool;
-             #else
-              typedef _Bool Bool;
-              #ifndef bool
-               "error: bool is not defined"
-              #endif
-              #ifndef false
-               "error: false is not defined"
-              #endif
-              #if false
-               "error: false is not 0"
-              #endif
-              #ifndef true
-               "error: true is not defined"
-              #endif
-              #if true != 1
-               "error: true is not 1"
-              #endif
+           [[#include <stdbool.h>
+
+             /* "true" and "false" should be usable in #if expressions and
+                integer constant expressions, and "bool" should be a valid
+                type name.
+
+                Although C 1999 requires bool, true, and false to be macros,
+                C 2023 and C++ 2011 overrule that, so do not test for that.
+                Although C 1999 requires __bool_true_false_are_defined and
+                _Bool, C 2023 says they are obsolescent, so do not require
+                them.  */
+
+             #if !true
+               #error "'true' is not true"
+             #endif
+             #if true != 1
+               #error "'true' is not equal to 1"
              #endif
+             char b[true == 1 ? 1 : -1];
+             char c[true];
 
-             #ifndef __bool_true_false_are_defined
-              "error: __bool_true_false_are_defined is not defined"
+             #if false
+               #error "'false' is not false"
+             #endif
+             #if false != 0
+               #error "'false' is not equal to 0"
              #endif
+             char d[false == 0 ? 1 : -1];
+
+             enum { e = false, f = true, g = false * true, h = true * 256 };
+
+             char i[(bool) 0.5 == true ? 1 : -1];
+             char j[(bool) 0.0 == false ? 1 : -1];
+             char k[sizeof (bool) > 0 ? 1 : -1];
+
+             struct sb { bool s: 1; bool t; } s;
+             char l[sizeof s.t > 0 ? 1 : -1];
 
-             struct s { Bool s: 1; Bool t; bool u: 1; bool v; } s;
-
-             char a[true == 1 ? 1 : -1];
-             char b[false == 0 ? 1 : -1];
-             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
-             char d[(bool) 0.5 == true ? 1 : -1];
-             /* See body of main program for 'e'.  */
-             char f[(Bool) 0.0 == false ? 1 : -1];
-             char g[true];
-             char h[sizeof (Bool)];
-             char i[sizeof s.t];
-             enum { j = false, k = true, l = false * true, m = true * 256 };
              /* The following fails for
                 HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
-             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];
+             bool m[h];
+             char n[sizeof m == h * sizeof m[0] ? 1 : -1];
+             char o[-1 - (bool) 0 < 0 ? 1 : -1];
              /* Catch a bug in an HP-UX C compiler.  See
                 https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
                 https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html
               */
-             Bool q = true;
-             Bool *pq = &q;
-             bool *qq = &q;
+             bool p = true;
+             bool *pp = &p;
            ]],
            [[
-             bool e = &s;
-             *pq |= q; *pq |= ! q;
-             *qq |= q; *qq |= ! 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 + !qq);
+             bool ps = &s;
+             *pp |= p;
+             *pp |= ! p;
+
+             /* Refer to every declared value, so they cannot be
+                discarded as unused.  */
+             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !j + !k
+                     + !l + !m + !n + !o + !p + !pp + !ps);
            ]])],
         [ac_cv_header_stdbool_h=yes],
         [ac_cv_header_stdbool_h=no])])
-   AC_CHECK_TYPES([_Bool])
-])
+])# AC_CHECK_HEADER_STDBOOL
+
+]) # m4_version_prereq 2.72
diff --git a/tests/test-stdbool.c b/tests/test-stdbool.c
index 3574a9e72f..27fd16d010 100644
--- a/tests/test-stdbool.c
+++ b/tests/test-stdbool.c
@@ -35,35 +35,30 @@
 
 #include <stdbool.h>
 
-#ifndef bool
- "error: bool is not defined"
-#endif
-#ifndef false
- "error: false is not defined"
-#endif
 #if false
  "error: false is not 0"
 #endif
-#ifndef true
- "error: true is not defined"
-#endif
 #if true != 1
  "error: true is not 1"
 #endif
-#ifndef __bool_true_false_are_defined
- "error: __bool_true_false_are_defined is not defined"
-#endif
 
 /* Several tests cannot be guaranteed with gnulib's <stdbool.h>, at
    least, not for all compilers and compiler options.  */
-#if HAVE_STDBOOL_H || 3 <= __GNUC__ || 4 <= __clang_major__
-struct s { _Bool s: 1; _Bool t; } s;
+#if (202311 <= __STDC_VERSION__ || defined __cplusplus \
+     || HAVE_STDBOOL_H || 3 <= __GNUC__ || 4 <= __clang_major__)
+# define WORKING_BOOL 1
+#else
+# define WORKING_BOOL 0
+#endif
+
+#if WORKING_BOOL
+struct s { bool s: 1; bool t; } s;
 #endif
 
 char a[true == 1 ? 1 : -1];
 char b[false == 0 ? 1 : -1];
 char c[__bool_true_false_are_defined == 1 ? 1 : -1];
-#if HAVE_STDBOOL_H || 3 <= __GNUC__ || 4 <= __clang_major__ /* See above.  */
+#if WORKING_BOOL
 char d[(bool) 0.5 == true ? 1 : -1];
 # ifdef ADDRESS_CHECK_OKAY /* Avoid gcc warning.  */
 /* C99 may plausibly be interpreted as not requiring support for a cast from
@@ -73,30 +68,30 @@ char d[(bool) 0.5 == true ? 1 : -1];
 bool e = &s;
 #  endif
 # endif
-char f[(_Bool) 0.0 == false ? 1 : -1];
+char f[(bool) 0.0 == false ? 1 : -1];
 #endif
 char g[true];
-char h[sizeof (_Bool)];
-#if HAVE_STDBOOL_H || 3 <= __GNUC__ || 4 <= __clang_major__ /* See above.  */
+char h[sizeof (bool)];
+#if WORKING_BOOL
 char i[sizeof s.t];
 #endif
 enum { j = false, k = true, l = false * true, m = true * 256 };
-_Bool n[m];
+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];
+char p[-1 - (bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
 /* Catch a bug in an HP-UX C compiler.  See
    https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
    https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html
  */
-_Bool q = true;
-_Bool *pq = &q;
+bool q = true;
+bool *pq = &q;
 
 int
 main ()
 {
   int error = 0;
 
-#if HAVE_STDBOOL_H || 3 <= __GNUC_ || 4 <= __clang_major___ /* See above.  */
+#if WORKING_BOOL
 # ifdef ADDRESS_CHECK_OKAY /* Avoid gcc warning.  */
   /* A cast from a variable's address to bool is valid in expressions.  */
   {
-- 
2.34.1


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

  Powered by Linux