#define MUTABLE_IO(p) ((IO *)MUTABLE_PTR(p))
#define MUTABLE_SV(p) ((SV *)MUTABLE_PTR(p))
-#ifdef I_STDBOOL
+#if defined(I_STDBOOL) && !defined(PERL_BOOL_AS_CHAR)
# include <stdbool.h>
# ifndef HAS_BOOL
# define HAS_BOOL 1
Andy Dougherty February 2000
*/
#ifdef __GNUG__ /* GNU g++ has bool built-in */
+# ifndef PERL_BOOL_AS_CHAR
# ifndef HAS_BOOL
# define HAS_BOOL 1
# endif
+# endif
#endif
/* The NeXT dynamic loader headers will not build with the bool macro
#endif /* NeXT || __NeXT__ */
#ifndef HAS_BOOL
+# ifdef bool
+# undef bool
+# endif
# define bool char
# define HAS_BOOL 1
#endif
# include <sys/sysctl.h>
#endif
-#ifdef USE_NSGETEXECUTABLEPATH
-# include <mach-o/dyld.h>
-#endif
-
#ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
# ifdef I_SYSUIO
# include <sys/uio.h>
# define PERL_SAWAMPERSAND
#endif
+/* Include mach-o/dyld.h here for perl.c’s sake, since it may #define bool,
+ and handy.h needs to be able to re#define it under
+ -Accflags=-DPERL_BOOL_AS_CHAR. */
+#if defined(USE_NSGETEXECUTABLEPATH) && defined(PERL_IN_PERL_C)
+# include <mach-o/dyld.h>
+#endif
+
#include "handy.h"
#if defined(USE_LARGE_FILES) && !defined(NO_64_BIT_RAWIO)
However, as an 80% solution it is still effective, as it has caught
bugs in the past.
+=head2 When is a bool not a bool?
+
+On pre-C99 compilers, C<bool> is defined as equivalent to C<char>.
+Consequently assignment of any larger type to a C<bool> is unsafe and may
+be truncated. The C<cBOOL> macro exists to cast it correctly.
+
+On those platforms and compilers where C<bool> really is a boolean (C++,
+C99), it is easy to forget the cast. You can force C<bool> to be a C<char>
+by compiling with C<-Accflags=-DPERL_BOOL_AS_CHAR>. You may also wish to
+add C<-Accflags=-Werror=conversion> or your compiler's equivalent to make
+it impossible to ignore the unsafe truncations.
+
=head2 The .i Targets
You can expand the macros in a F<foo.c> file by saying