Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Mar 2013 00:02:22 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Hans Petter Selasky <hps@bitfrost.no>
Cc:        Davide Italiano <davide@FreeBSD.org>, src-committers@FreeBSD.org, John Baldwin <jhb@FreeBSD.org>, attilio@FreeBSD.org, Gleb Smirnoff <glebius@FreeBSD.org>, Bruce Evans <brde@optusnet.com.au>, svn-src-projects@FreeBSD.org
Subject:   Re: svn commit: r247710 - projects/calloutng/sys/kern
Message-ID:  <20130305232805.X1535@besplex.bde.org>
In-Reply-To: <5135DFD5.5050708@bitfrost.no>
References:  <201303031339.r23DdsBU047737@svn.freebsd.org> <201303041521.06557.jhb@freebsd.org> <CAJ-FndBvLD_fU1ZZ3cGNtChfdtXyuBRt4Z_ci8daS08ZYdOKzg@mail.gmail.com> <201303041620.52100.jhb@freebsd.org> <20130305201211.M902@besplex.bde.org> <20130305094819.GI48089@FreeBSD.org> <20130305214655.C1224@besplex.bde.org> <5135DFD5.5050708@bitfrost.no>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 5 Mar 2013, Hans Petter Selasky wrote:

> On 03/05/13 12:21, Bruce Evans wrote:
>> On Tue, 5 Mar 2013, Gleb Smirnoff wrote:
>> 
>>> On Tue, Mar 05, 2013 at 08:43:33PM +1100, Bruce Evans wrote:
>>> B> > I think for new code we should prefer C99's bool to boolean_t.
>>> B>
>>> B> Why?  There is no existing practice for this in the kernel.  There
>>> is some
>>> B> in the Linux kernel :-).
>>> 
>>> Why? Because it is standard. What for? To make it more easy for newcomers
>>> to start hacking on FreeBSD kernel.
>> 
>> I think you mean "harder".  Now the newcomers need to know:
>> - the old method, which is used in most places
>> - the new method
>> - style rules for old, new and mixed methods
>> - arcane C99 points like whether bool can be used in bit-fields (I had to
>>    look this up to check it.  It can).
>> 
>> I now see technical reasons to never use bool in kernel or other low-level
>> code.  It will cause minor pessimizations converting nonzero to true (1)
>> at runtime, and for converting bool to register_t when passing parameters
>> (bool is 1 byte on x86).  To use bool in structs (when not packing it into
>> bit-fields), we need to know too much about its size to pack it properly...
>
> I'm not sure how good you all are at C99. There is a subtle difference

I am a language lawyer for C90 and C99 :-).  I don't know much about C11
or C++.

> between bool (compiler type) and boolean_t (typedef'ed), and that is when 
> assigning an non-bool value. This is probably bad style, but I just want to 
> show you the difference:
>
> #include <stdbool.h>
> #include <stdio.h>
>
> typedef int             boolean_t;
>
> int main()
> {
> bool var1;
> var1 = 3;
> printf("%d\n", var1);
>
> boolean_t var2;
> var2 = 3;
> printf("%d\n", var2);
>
> return (0);
> }
>
> If defined correctly, var1 should contain a value of "1", and var2 should 
> contain a value of "3".

Yes, this is what I meant by the bool version being slower since it needs
conversions to translate 3 to 1.  Here the values are constant so the
compiler can do the conversions at compile time so as to not be slower,
but in general there will be some conversions at runtime.

Also, printf() is variadic, so bools cannot be passed to it.  The bool
undergoes the default promotions.  Again I fail my language lawyer's
exam and have to look up what these promotions are.  _Bool has rank <
char, so it promotes to int and thus your %d format is correct.

> Now if for some reason someone like possibly some 
> Linux guys do, use booleans for counting, you will have an instant error :-)

:-).

Both gcc and clang generate a move of 1 to `var' for the counting
expression `var++' on `_Bool var'.  I would prefer an error.  I'd
better take bools off the language lawyer's exam so that I pass :-).
POLA requires C99 to not specify a complete set of operations for
nonsensical operations on bools.  So apparently, this var++ is just
evaluated as an integer expression with promotions from and to bool.
var starts as 0 or 1 and so var + 1 is the integer 1 or 2.  Then
assigning var + 1 back to var gives the boolean 1.  Similarly,
var += INT_MAX gives either (bool)INT_MAX = 1, or undefined behaviour
so it can give boolean 1 in all cases.  Similarly var += UINT_MAX gives 
either (bool)UINT_MAX = 1, or defined behaviour (bool)0 = 0.  clang
optimizes the former to 1 and the latter to !!var (xor with 1), but
gcc evaluates them at runtime.

> I'm not saying we should take their example, but anyhow, be warned about the 
> difference between bool and boolean_t!

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130305232805.X1535>