Require sizeof(bool) == 1.
The C standard says that sizeof(bool) is implementation-defined, but we know of no current systems where it is not 1. The last known systems seem to have been Apple macOS/PowerPC 10.5 and Microsoft Visual C++ 4, both long defunct. PostgreSQL has always required sizeof(bool) == 1 for the definition of bool that it used, but previously it would define its own type if the system-provided bool had a different size. That was liable to cause memory layout problems when interacting with system and third-party libraries on (by now hypothetical) computers with wider _Bool, and now C23 has introduced a new problem by making bool a built-in datatype (like C++), so the fallback code doesn't even compile. We could probably work around that, but then we'd be writing new untested code for a computer that doesn't exist. Instead, delete the unreachable and C23-uncompilable fallback code, and let existing static assertions fail if the system-provided bool is too wide. If we ever get a problem report from a real system, then it will be time to figure out what to do about it in a way that also works on modern compilers. Note on C++: Previously we avoided including <stdbool.h> or trying to define a new bool type in headers that might be included by C++ code. These days we might as well just include <stdbool.h> unconditionally: it should be visible to C++11 but do nothing, just as in C23. We already include <stdint.h> without C++ guards in c.h, and that falls under the same C99-compatibility section of the C++11 standard as <stdbool.h>, so let's remove the guards here too. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/3198438.1731895163%40sss.pgh.pa.us
This commit is contained in:
parent
4b03a27faf
commit
97525bc5c8
41
configure
vendored
41
configure
vendored
@ -14958,47 +14958,6 @@ if test "$ac_cv_sizeof_off_t" -lt 8; then
|
|||||||
fi
|
fi
|
||||||
fi
|
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" "#include <stdbool.h>
|
|
||||||
"; 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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if test "$ac_cv_sizeof_bool" = 1; then
|
|
||||||
|
|
||||||
$as_echo "#define PG_USE_STDBOOL 1" >>confdefs.h
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Functions, global variables
|
## Functions, global variables
|
||||||
|
@ -1691,15 +1691,6 @@ if test "$ac_cv_sizeof_off_t" -lt 8; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_CHECK_SIZEOF([bool], [], [#include <stdbool.h>])
|
|
||||||
|
|
||||||
dnl We use <stdbool.h> if bool has size 1 after including it. Otherwise, c.h
|
|
||||||
dnl will fall back to declaring bool as unsigned char.
|
|
||||||
if test "$ac_cv_sizeof_bool" = 1; then
|
|
||||||
AC_DEFINE([PG_USE_STDBOOL], 1,
|
|
||||||
[Define to 1 to use <stdbool.h> to define type bool.])
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Functions, global variables
|
## Functions, global variables
|
||||||
|
@ -1755,13 +1755,6 @@ if cc.compiles('''
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
# We use <stdbool.h> if bool has size 1 after including it. Otherwise, c.h
|
|
||||||
# will fall back to declaring bool as unsigned char.
|
|
||||||
if cc.sizeof('bool', prefix: '#include <stdbool.h>', args: test_c_args) == 1
|
|
||||||
cdata.set('PG_USE_STDBOOL', 1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
# Need to check a call with %m because netbsd supports gnu_printf but emits a
|
# Need to check a call with %m because netbsd supports gnu_printf but emits a
|
||||||
# warning for each use of %m.
|
# warning for each use of %m.
|
||||||
printf_attributes = ['gnu_printf', '__syslog__', 'printf']
|
printf_attributes = ['gnu_printf', '__syslog__', 'printf']
|
||||||
|
@ -117,11 +117,9 @@ ExecEvalBoolSubroutineTemplate(ExprState *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clang represents stdbool.h style booleans that are returned by functions
|
* Clang represents bool returned by functions differently (as i1) than stored
|
||||||
* differently (as i1) than stored ones (as i8). Therefore we do not just need
|
* ones (as i8). Therefore we do not just need TypeStorageBool (above), but
|
||||||
* TypeBool (above), but also a way to determine the width of a returned
|
* also a way to determine the width of a returned integer.
|
||||||
* integer. This allows us to keep compatible with non-stdbool using
|
|
||||||
* architectures.
|
|
||||||
*/
|
*/
|
||||||
extern bool FunctionReturningBool(void);
|
extern bool FunctionReturningBool(void);
|
||||||
bool
|
bool
|
||||||
|
@ -18,16 +18,6 @@
|
|||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* On macOS, <dlfcn.h> insists on including <stdbool.h>. If we're not
|
|
||||||
* using stdbool, undef bool to undo the damage.
|
|
||||||
*/
|
|
||||||
#ifndef PG_USE_STDBOOL
|
|
||||||
#ifdef bool
|
|
||||||
#undef bool
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif /* !WIN32 */
|
#endif /* !WIN32 */
|
||||||
|
|
||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
|
@ -450,37 +450,11 @@ typedef void (*pg_funcptr_t) (void);
|
|||||||
* bool
|
* bool
|
||||||
* Boolean value, either true or false.
|
* Boolean value, either true or false.
|
||||||
*
|
*
|
||||||
* We use stdbool.h if bool has size 1 after including it. That's useful for
|
* PostgreSQL currently cannot deal with bool of size other than 1; there are
|
||||||
* better compiler and debugger output and for compatibility with third-party
|
* static assertions around the code to prevent that.
|
||||||
* libraries. But PostgreSQL currently cannot deal with bool of other sizes;
|
|
||||||
* there are static assertions around the code to prevent that.
|
|
||||||
*
|
|
||||||
* For C++ compilers, we assume the compiler has a compatible built-in
|
|
||||||
* definition of bool.
|
|
||||||
*
|
|
||||||
* See also the version of this code in src/interfaces/ecpg/include/ecpglib.h.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
|
|
||||||
#ifdef PG_USE_STDBOOL
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#else
|
|
||||||
|
|
||||||
#ifndef bool
|
|
||||||
typedef unsigned char bool;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef true
|
|
||||||
#define true ((bool) 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef false
|
|
||||||
#define false ((bool) 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* not PG_USE_STDBOOL */
|
|
||||||
#endif /* not C++ */
|
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
|
@ -597,9 +597,6 @@
|
|||||||
/* Define to best printf format archetype, usually gnu_printf if available. */
|
/* Define to best printf format archetype, usually gnu_printf if available. */
|
||||||
#undef PG_PRINTF_ATTRIBUTE
|
#undef PG_PRINTF_ATTRIBUTE
|
||||||
|
|
||||||
/* Define to 1 to use <stdbool.h> to define type bool. */
|
|
||||||
#undef PG_USE_STDBOOL
|
|
||||||
|
|
||||||
/* PostgreSQL version as a string */
|
/* PostgreSQL version as a string */
|
||||||
#undef PG_VERSION
|
#undef PG_VERSION
|
||||||
|
|
||||||
@ -630,9 +627,6 @@
|
|||||||
RELSEG_SIZE requires an initdb. */
|
RELSEG_SIZE requires an initdb. */
|
||||||
#undef RELSEG_SIZE
|
#undef RELSEG_SIZE
|
||||||
|
|
||||||
/* The size of `bool', as computed by sizeof. */
|
|
||||||
#undef SIZEOF_BOOL
|
|
||||||
|
|
||||||
/* The size of `long', as computed by sizeof. */
|
/* The size of `long', as computed by sizeof. */
|
||||||
#undef SIZEOF_LONG
|
#undef SIZEOF_LONG
|
||||||
|
|
||||||
|
@ -6,6 +6,3 @@
|
|||||||
|
|
||||||
/* Define to 1 if `long long int' works and is 64 bits. */
|
/* Define to 1 if `long long int' works and is 64 bits. */
|
||||||
#undef HAVE_LONG_LONG_INT_64
|
#undef HAVE_LONG_LONG_INT_64
|
||||||
|
|
||||||
/* Define to 1 to use <stdbool.h> to define type bool. */
|
|
||||||
#undef PG_USE_STDBOOL
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#ifndef _ECPGLIB_H
|
#ifndef _ECPGLIB_H
|
||||||
#define _ECPGLIB_H
|
#define _ECPGLIB_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "ecpg_config.h"
|
#include "ecpg_config.h"
|
||||||
@ -14,35 +15,6 @@
|
|||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
#include "sqlca.h"
|
#include "sqlca.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a small extract from c.h since we don't want to leak all postgres
|
|
||||||
* definitions into ecpg programs; but we need to know what bool is.
|
|
||||||
*/
|
|
||||||
#ifndef __cplusplus
|
|
||||||
|
|
||||||
#ifdef PG_USE_STDBOOL
|
|
||||||
#include <stdbool.h>
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We assume bool has been defined if true and false are. This avoids
|
|
||||||
* duplicate-typedef errors if this file is included after c.h.
|
|
||||||
*/
|
|
||||||
#if !(defined(true) && defined(false))
|
|
||||||
typedef unsigned char bool;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef true
|
|
||||||
#define true ((bool) 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef false
|
|
||||||
#define false ((bool) 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* not PG_USE_STDBOOL */
|
|
||||||
#endif /* not C++ */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
@ -5,7 +5,6 @@ ecpg_inc = include_directories('.')
|
|||||||
ecpg_conf_keys = [
|
ecpg_conf_keys = [
|
||||||
'HAVE_LONG_INT_64',
|
'HAVE_LONG_INT_64',
|
||||||
'HAVE_LONG_LONG_INT_64',
|
'HAVE_LONG_LONG_INT_64',
|
||||||
'PG_USE_STDBOOL',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
ecpg_conf_data = configuration_data()
|
ecpg_conf_data = configuration_data()
|
||||||
|
@ -72,16 +72,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Regarding bool, both PostgreSQL and Perl might use stdbool.h or not,
|
* Define HAS_BOOL here so that Perl does not redefine bool. We included
|
||||||
* depending on configuration. If both agree, things are relatively harmless.
|
* <stdbool.h> in c.h.
|
||||||
* If not, things get tricky. If PostgreSQL does but Perl does not, define
|
|
||||||
* HAS_BOOL here so that Perl does not redefine bool; this avoids compiler
|
|
||||||
* warnings. If PostgreSQL does not but Perl does, we need to undefine bool
|
|
||||||
* after we include the Perl headers; see below.
|
|
||||||
*/
|
*/
|
||||||
#ifdef PG_USE_STDBOOL
|
|
||||||
#define HAS_BOOL 1
|
#define HAS_BOOL 1
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the basic Perl API. We use PERL_NO_GET_CONTEXT mode so that our code
|
* Get the basic Perl API. We use PERL_NO_GET_CONTEXT mode so that our code
|
||||||
@ -180,19 +174,6 @@
|
|||||||
/* perl version and platform portability */
|
/* perl version and platform portability */
|
||||||
#include "ppport.h"
|
#include "ppport.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* perl might have included stdbool.h. If we also did that earlier (see c.h),
|
|
||||||
* then that's fine. If not, we probably rejected it for some reason. In
|
|
||||||
* that case, undef bool and proceed with our own bool. (Note that stdbool.h
|
|
||||||
* makes bool a macro, but our own replacement is a typedef, so the undef
|
|
||||||
* makes ours visible again).
|
|
||||||
*/
|
|
||||||
#ifndef PG_USE_STDBOOL
|
|
||||||
#ifdef bool
|
|
||||||
#undef bool
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* supply HeUTF8 if it's missing - ppport.h doesn't supply it, unfortunately */
|
/* supply HeUTF8 if it's missing - ppport.h doesn't supply it, unfortunately */
|
||||||
#ifndef HeUTF8
|
#ifndef HeUTF8
|
||||||
#define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \
|
#define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user