This is the mail archive of the
mailing list for the GCC project.
Re: PATCH to libcpp: Move to the intersection of C90 an C++
Gabriel Dos Reis <firstname.lastname@example.org> writes:
> Patch committed.
> | On May 23, 2005, at 9:33 PM, Gabriel Dos Reis wrote:
> | > #define bool unsigned char
> Zack suggested not making that #define conditional on __cpluscplus,
> e.g. have bool always replaced with "unsigned char" (as it was until
> this patch).
I'm going to try one more time to explain why this is necessary, in
both gcc and libcpp (and any other library which gets linked into the
compiler). I'm not concerned with interface compatibility or bugs in
the bootstrap compiler. I'm concerned with the different arithmetic
semantics of a true boolean type from 'unsigned char'. They make it
possible for a program to be correct when compiled with a true boolean
type, incorrect when compiled with 'unsigned char' used as a fake
boolean type, even if all parts of the program make the same choice.
I've attached a demonstration program to this message. This is what
it prints when it's using C++ 'bool':
$ g++ test.c && ./a.out
have_a=1 have_b=1 have_a&&have_b=1
and when it's using 'unsigned char' instead:
$ gcc test.c && ./a.out
test.c: In function `main':
test.c:14: warning: initialization makes integer from pointer without a cast
test.c:15: warning: initialization makes integer from pointer without a cast
have_a=0 have_b=0 have_a&&have_b=0
[Obviously, the a= and b= numbers will differ somewhat between
My demonstration is contrived, but in the time when we were using C99
_Bool, we had several bugs of exactly this form: people would test
their code with GCC on Linux, hence _Bool was in use, and then someone
would try to bootstrap starting from a non-GCC compiler and it
wouldn't work. ("Wouldn't work" encompasses both warnings (which are
promoted to errors in a GCC build) and incorrect runtime behavior -
my demonstration deliberately provokes both; there exist cases that
provoke either but not the other.)
My objection is because, if someone gets in the habit of testing only
with a C++ compiler, they may introduce code which is incorrect in
this way when 'bool' has the semantics of unsigned char, and thus
break the compiler for people still using a C compiler.
> (1) gcc/ correctly leaves "bool" to what it means if being compiled
> with a C++ compiler.
For the reasons stated above, gcc/ is wrong to do this.
> So, there is obvious mismatch here. That is no good. Both gcc/
> and libcpp/ shall have the same meaning of bool.
I do agree with this statement, for the record.
> If the GCC developer community really feels that "bool", when GCC is
> being compiled with a C++ compiler, shall not mean what it means in
> a C++ program, then it shall be renamed to something else e.g. Bool,
> Boolean or gccbool or ..., as otherwise the unconditional #define
> directly conflicts with our own coding convention.
I don't think renaming is necessary - for correctness, it should
suffice to enforce that every piece of code involved does
#define bool unsigned char. However, I do agree that this is a
confusing usurpation of the name, and if you want to do the renaming
I won't stop you. (I suggest the name "gcc_boolean", parallel with
#define bool unsigned char
void *a = memalign (1<<CHAR_BIT, 1<<CHAR_BIT);
void *b = memalign (1<<CHAR_BIT, 1<<CHAR_BIT);
bool have_a = a;
bool have_b = b;
printf("a=%p b=%p\n", a, b);
printf("have_a=%d have_b=%d have_a&&have_b=%d\n",
have_a, have_b, have_a && have_b);