Hello all,
I heard an opinion on the use of the | operator together with C99
conform bool types (stdbool.h)
My discussion partner stated that
_Bool a, b;
......
a | b;
should be forbidden and a || b should be used instead.
I personally can't see the difference for true boolean types (which
would be *implementation* specific, but let's assume an embedded
compiler with a true bool type that maps to a real bit.)
His assertion that it "should be forbidden" is somewhat ambiguous. If
he's suggesting that you should be forbidden to write that, because it
is not permitted in C99, he's wrong. However, he could also be
suggesting that, while it is currently permitted, it should not be.
If so, then he might be talking about the idea, which has frequently
been discussed, that it was a mistake for C to conflate arithmetic and
boolean values the way that it does. I tend to agree, but it's not
feasible to change that aspect of C without breaking a LOT of code
(including most of mine: since C does conflate them, I make heavy use of
that fact in my code).
To make this idea clearer, let me outline how a new C-like language that
implemented this idea would differ from C:
* in C, _Bool is a standard unsigned integer type. As such, it is also a
member of the several other type categories: "unsigned", "standard",
"integer", "basic", "real", "arithmetic", "scalar", and "object". In
this new language, _Bool would only be a member of the last two of those
type categories.
* All relational and equality comparisons result in a _Bool value, even
in #if expressions.
* All of the following are constrained to be of type _Bool:
- The operands of all logical operators (!, &&, ||)
- The first operand of ?:
- The condition in if(), while() and do while() statements
- The condition in #if directives.
* There are no conversions, implicit or explicit, permitted between
_Bool and other types. The equivalent of converting scalar_value to
_Bool can be performed by "scalar_value==0", and the equivalent of
conversion from _Bool can be performed by "boolean_value ? 1 : 0".
* Values of type _Bool are not implicitly promoted to 'int'.
In such a language, a|b would be an error, because bitwise-or requires
that it's operands have integer type. If you actually needed to express
the same idea, you could write (a?1:0)|(b?1:0), or (a||b)?1:0. Yes,
those expressions are clumsier - but that's precisely the point: the
increased clumsiness is supposed to make it easier for you to stop and
think "does it really make sense to do this?" - the answer will often be
"No". The idea is that things which often make sense should be easier to
write than things that do not usually make sense.