[PATCH v5 4/4] Use stdbool.h if available
Peter Eisentraut <peter_e@gmx.net>
From: Peter Eisentraut <peter_e@gmx.net>
To:
Date: 2017-08-16T04:22:32Z
Lists: pgsql-hackers
While we could do without this, extension code and third-party headers
are increasingly pulling this in, creating possible complications. One,
bool defined in stdbool.h is not necessarily one byte in size. Two, it
can only contain values 0 or 1 on output. So having multiple
definitions of bool in play depending on include file order could create
a mess.
So we just get on board with this and use stdbool.h always if available.
As a benefit, some recent compilers can give some better warnings if the
official bool type is used.
---
configure | 213 ++++++++++++++++++++++++++++++++++++---------
configure.in | 7 ++
src/include/c.h | 10 ++-
src/include/pg_config.h.in | 9 ++
src/pl/plperl/plperl.h | 10 +--
5 files changed, 202 insertions(+), 47 deletions(-)
diff --git a/configure b/configure
index d9b7b8d7ec..36f5550720 100755
--- a/configure
+++ b/configure
@@ -1996,116 +1996,116 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_func
-# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
-# ----------------------------------------------------
-# Tries to find if the field MEMBER exists in type AGGR, after including
-# INCLUDES, setting cache variable VAR accordingly.
-ac_fn_c_check_member ()
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
-$as_echo_n "checking for $2.$3... " >&6; }
-if eval \${$4+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
+ eval "$3=no"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-$5
+$4
int
main ()
{
-static $2 ac_aggr;
-if (ac_aggr.$3)
-return 0;
+if (sizeof ($2))
+ return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
- eval "$4=yes"
-else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-$5
+$4
int
main ()
{
-static $2 ac_aggr;
-if (sizeof ac_aggr.$3)
-return 0;
+if (sizeof (($2)))
+ return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
- eval "$4=yes"
+
else
- eval "$4=no"
+ eval "$3=yes"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-eval ac_res=\$$4
+eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-} # ac_fn_c_check_member
+} # ac_fn_c_check_type
-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-# -------------------------------------------
-# Tests whether TYPE exists after having included INCLUDES, setting cache
-# variable VAR accordingly.
-ac_fn_c_check_type ()
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
$as_echo_n "(cached) " >&6
else
- eval "$3=no"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-$4
+$5
int
main ()
{
-if (sizeof ($2))
- return 0;
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-$4
+$5
int
main ()
{
-if (sizeof (($2)))
- return 0;
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
-
+ eval "$4=yes"
else
- eval "$3=yes"
+ eval "$4=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-eval ac_res=\$$3
+eval ac_res=\$$4
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-} # ac_fn_c_check_type
+} # ac_fn_c_check_member
# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
# --------------------------------------------
@@ -10683,6 +10683,100 @@ fi
## Header files
##
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if ${ac_cv_header_stdbool_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #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
+
+ struct s { _Bool s: 1; _Bool t; } 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];
+ /* Catch a bug in an HP-UX C compiler. See
+ http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+ http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+ */
+ _Bool q = true;
+ _Bool *pq = &q;
+
+int
+main ()
+{
+
+ bool e = &s;
+ *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);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdbool_h=yes
+else
+ ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+ ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
+
for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -12861,6 +12955,43 @@ if test "$ac_cv_sizeof_off_t" -lt 8 -a "$segsize" != "1"; then
as_fn_error $? "Large file support is not enabled. Segment size cannot be larger than 1GB." "$LINENO" 5
fi
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of bool" >&5
+$as_echo_n "checking size of bool... " >&6; }
+if ${ac_cv_sizeof_bool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (bool))" "ac_cv_sizeof_bool" "#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif
+"; then :
+
+else
+ if test "$ac_cv_type_bool" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (bool)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_bool=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_bool" >&5
+$as_echo "$ac_cv_sizeof_bool" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_BOOL $ac_cv_sizeof_bool
+_ACEOF
+
+
+
##
## Functions, global variables
diff --git a/configure.in b/configure.in
index 5245899109..fd03711176 100644
--- a/configure.in
+++ b/configure.in
@@ -1149,6 +1149,8 @@ AC_SUBST(UUID_LIBS)
## Header files
##
+AC_HEADER_STDBOOL
+
AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
# On BSD, test for net/if.h will fail unless sys/socket.h
@@ -1407,6 +1409,11 @@ if test "$ac_cv_sizeof_off_t" -lt 8 -a "$segsize" != "1"; then
AC_MSG_ERROR([Large file support is not enabled. Segment size cannot be larger than 1GB.])
fi
+AC_CHECK_SIZEOF([bool], [],
+[#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif])
+
##
## Functions, global variables
diff --git a/src/include/c.h b/src/include/c.h
index 1d656e37d5..e9cf1a7ee4 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -247,14 +247,20 @@
* bool
* Boolean value, either true or false.
*
- * XXX for C++ compilers, we assume the compiler has a compatible
+ * Use stdbool.h if available, to ensure best compatibility with third-party
+ * libraries. For C++ compilers, we assume the compiler has a compatible
* built-in definition of bool.
*/
#ifndef __cplusplus
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#else
+
#ifndef bool
typedef char bool;
+#undef SIZEOF_BOOL
#define SIZEOF_BOOL 1
#endif
@@ -266,6 +272,8 @@ typedef char bool;
#define false ((bool) 0)
#endif
+#endif /* not HAVE_STDBOOL_H */
+
#endif /* not C++ */
/*
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 0aa6be4666..b7d00d4164 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -479,6 +479,9 @@
/* Define to 1 if you have the `SSL_get_current_compression' function. */
#undef HAVE_SSL_GET_CURRENT_COMPRESSION
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@@ -678,6 +681,9 @@
/* Define to 1 if you have the <winldap.h> header file. */
#undef HAVE_WINLDAP_H
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
/* Define to 1 if your compiler understands __builtin_bswap16. */
#undef HAVE__BUILTIN_BSWAP16
@@ -787,6 +793,9 @@
RELSEG_SIZE requires an initdb. */
#undef RELSEG_SIZE
+/* The size of `bool', as computed by sizeof. */
+#undef SIZEOF_BOOL
+
/* The size of `long', as computed by sizeof. */
#undef SIZEOF_LONG
diff --git a/src/pl/plperl/plperl.h b/src/pl/plperl/plperl.h
index aac95f8d2c..d8030398de 100644
--- a/src/pl/plperl/plperl.h
+++ b/src/pl/plperl/plperl.h
@@ -50,6 +50,11 @@
#define __inline__ inline
#endif
+/*
+ * Prevent perl from redefining "bool".
+ */
+#define HAS_BOOL 1
+
/*
* Get the basic Perl API. We use PERL_NO_GET_CONTEXT mode so that our code
@@ -91,11 +96,6 @@
#define NEED_sv_2pv_flags
#include "ppport.h"
-/* perl may have a different width of "bool", don't buy it */
-#ifdef bool
-#undef bool
-#endif
-
/* supply HeUTF8 if it's missing - ppport.h doesn't supply it, unfortunately */
#ifndef HeUTF8
#define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \
--
2.15.1
--------------AB99891BACB265862555DF3C--