standards/60772: _Bool and bool should be unsigned

Bruce Evans bde at zeta.org.au
Wed Dec 31 20:57:16 PST 2003


On Wed, 31 Dec 2003, Jason Evans wrote:

> >Release:        FreeBSD 4.9-RC i386
                   ^^^^^^^^^^^

> >Description:
> 	_Bool and bool must be unsigned, so that structure bit fields work as
> 	expected.
> >How-To-Repeat:
> #include <stdio.h>
> #include <stdbool.h>
>
> /* _Bool and bool must be unsigned.  Otherwise, stucture bit fields do not work
>  * correctly, due to how sign extension works. */
>
> struct foo {
> 	bool white:1; /* Note :1 (bit field). */
> };

This works correctly with C99 compilers, e.g., in with the not-quite-C99
compiler gcc in -current and even with the non-C99 compiler "gcc -c89"
in -current, since bool is an alias for _Bool and _Bool is a builtin
type (neither signed nor unsigned) that can only represent the values
0 and 1.

>
> struct bar {
> 	bool white:2;
> };

This also doesn't really work in FreeBSD-4.9, since it can store more
than the values of 0 and 1.  Similarly for a non-bitfield.  The fake
definition in FreeBSD-4.9 permits storing values between INT_MIN and
INT_MAX, and changing it to unsigned so that it is limited to values
between 0 and UINT_MAX isn't much of an improvment.

> >Fix:
> Using bit fields with more than one bit works around the problem, but is
> not a satisfactory workaround.  This bug can cause obscure problems, since
> something like:
>
> 	if (foo.white == true) ...;
>
> breaks.

I think the correct fix is to remove <stdbool.h> in RELENG_4, since it is
impossible to implement it correctly.  It's more dangerous than it used
to be since programs that use it are more likely to expect it to give C99
semantics.  Was there a defacto standard for it before C99?  It doesn't
seem to have been very common -- it isn't in glibc-2.2.5 (which is 2 years
old, but not as old as <stdnool.h> in FreeBSD).

Bruce


More information about the freebsd-standards mailing list