[U-Boot] [PATCH] Introduce a global bool type

Albert ARIBAUD albert.u.boot at aribaud.net
Sat Jan 19 10:30:30 CET 2013


Hi Wolfgang,

My 2 EUR cents:

On Tue, 08 Jan 2013 20:07:15 +0100, Wolfgang Denk <wd at denx.de> wrote:

(sorry for the late chiming in)

> Dear Timur Tabi,
> 
> In message <50EC5D29.1070408 at freescale.com> you wrote:
> >
> > > _Bool has been introduced very late to any C standard, and you can
> > > still see this from the ugly, unnatural name.
> > 
> > It was introduced in C99, which is over 12 years old.
> 
> And how old is C?   I think the "official" announcment was 1972, so
> that's more than twice as long without that addition.
> 
> > > work wit than a CLI.  And I've seen more than one case where bugs were
> > > caused by using "proper bool types" like this:
> > > 
> > > 	i = 0;
> > > 	j = 0;
> > > 	k = 2;
> > > 
> > > 	if ((i | j | k) == true) ...
> 
> > Ok, but this is just wrong.  i, j, and k are not boolean types, so they
> > should not be compared with 'true' or 'false'.  I don't think you'll find
> > any disagreement with that.
> 
> You are right.  And I wrote that it's a bug.  But this is what you can
> easily get from using boolean types.  This is example has not been
> invented by me.  I don't even claim that this was good programming
> style - all I want to say is that from what I have seen the boolean
> types are not a panacea; they cause new problems as well.

Ok, so there are three things in Wolfgang's example: a lax boolean (set
to 2), a mix-up between bitwise and boolean operators (which a compiler
may or may not detect or at least flag as suspicious), and finally a
comparison of the lax boolean (2) with a strict boolean (true, equal
to 1) which will fail.

I guess we're all aware of this type of problem. To avoid it, I
personally try to apply the Postel principle here: be conservative in
what you do, thus only produce strict boolean objects, and be liberal
in what you get, i.e. consider all boolean expressions to be lax.

This means that as far as coding practice is concerned, I tend to favor
the style set forth in the next three lines, where I always compute 
booleans with true and false and boolean operators, but test them
'zero/nonzero':

	/* what I favor */
	clk_is_enabled = ((reg_val >> 9) & 1) ? true: false;
	ip_is_enabled = clk_is_enabled && pwd_is_enabled;
	if (clk_is_enabled) { ...

rather than assigning them 'zero/nonzero', or using bitwise ops on
booleans, or testing against boolean constants (although I concede
that the first line below wins over its counterpart above as far as
concision is concerned).

	/* what I don't favor */
	clk_is_enabled = ((register >> 9) & 1);
	ip_is_enabled = clk_is_enabled & pwd_is_enabled;
	if (clk_is_enabled == true) { ...

This way I am sure to evaluate any nonzero value as 'true', so lax code
can safely pass me lax booleans, and I am sure that my booleans equal 1
when true, so I always pass strict booleans to strict code.

Oh, and I also try to wisely name boolean objects, so that they read out
loud as a boolean statement, e.g. "clock is enabled", but this is a bit
(more) beside the point.

> Best regards,
> 
> Wolfgang Denk

Amicalement,
-- 
Albert.


More information about the U-Boot mailing list