karl@haddock.ima.isc.com (Karl Heuer) (09/06/90)
This is getting off-topic for comp.lang.c, so I'm taking it to alt.lang.cfutures. In articles <5398@harrier.ukc.ac.uk> <5409@harrier.ukc.ac.uk> mtr@ukc.ac.uk (M.T.Russell) writes: >I'd be interested to see some experiments with adding a `bool' type to a >C compiler (gcc?), with the following semantics: > >- bool has the same size and representation as int. Why guarantee anything of the sort? Leave it up to the implementation. A smart compiler can even pack them into single bits when appropriate. (Those 12 flags declared `register bool' in main() might as well share one register!) >- `if', `do/while', `while' and `for' demand a bool expression > as the test. Note that `if (ptr)' is still allowed by the > implicit rewrite to `if (ptr != 0)'. I'd strike that last sentence. If you're going to add strict-checking Booleans, then the user should have to make the comparison explicitly, whether the operand is a pointer or any arithmetic type. >- assignment and comparison between bool and arithmetic types > is illegal without a cast. I suppose a cast could be legal, though I think `b=(i!=0)' and `i=(b?1:0)' are better ways to write the conversions. >If `typedef int bool;' was allowed as a special case, then code portability >wouldn't be affected. ... I'd also turn on a macro __BOOL__ to indicate that >the extension was there, so that applications could say: > #ifndef __BOOL__ > typedef int bool; > #define TRUE 1 > #define FALSE 0 > #endif Better yet, here's how to retain full backward compatibility. I'll phrase it in terms of what I think the ANSI Standard should have (roughly) said: The implementation shall provide a header <bool.h>. It defines the type "bool" and the constants "TRUE" and "FALSE" of that type. Including this header may also enable strict typechecking of Booleans. Thus, an implementation is conforming by simply providing this header with the single line "typedef enum { FALSE, TRUE } bool;", but a stricter implementation may choose to say #pragma enable_warnings_strict_bool typedef __builtin_bool bool; #define TRUE __builtin_true #define FALSE __builtin_false All operators that are conceptually Boolean (e.g. "<") return a result of type bool, not int. All the obvious operators and statements (e.g. "if()") expect an expression of type bool, not int. A bool which appears in an int context is automatically converted as if by `b?1:0', and an int (or pointer) that appears in a bool context is automatically converted as if by `i!=0'. (Backward compatibility.) Common warnings: the program has an implicit conversion involving a bool. (Alternately, we could say that these conversions are simply illegal if <bool.h> has been used, but I anticipate objections from the weenies who think "j/(i+!i)" is a feature instead of a flaw.) Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint (P.S. I'd rather see YES/NO instead of TRUE/FALSE, but I expect I'm outvoted.)
karl@haddock.ima.isc.com (Karl Heuer) (09/10/90)
In article <1990Sep7.003709.4853@laguna.ccsf.caltech.edu> jimmy@tybalt.caltech.edu (Jimmy Hu) writes: >[I don't want stronger type-checking; I want to be able to write >"d = (a==b)*c;" and "if (flags & 0x0800)".] In my other article in alt.lang.cfutures (to which I'm redirecting followups), I acknowledged the existence of this style of programming. And of course it would continue to be legal as long as we're talking about C rather than a completely new language; there are too many people (and dusty decks) who agree with you. My proposal was that the implementation could enable strict typechecking of Booleans only when <bool.h> is included, so your code would continue to work. Those of us who use the stricter model will write out the conversions that are implicit in your example (i.e. "d = (a==b?1:0)*c;" and "if ((flags & 0x0800) != 0)", which btw should be just as efficient since that's what the compiler will probably generate anyway, unless it really has a machine instruction that compares two integers and sets a register to zero or one instead of setting a condition code or something) and would use the hypothetical standard <bool.h>, and get a compiler error rather than the wrong answer when finger slippage puts the wrong operator in the code (the classic example being "if (a=b)", and Yes I know that some linters already check for this specific case; I'm just asking for a more general check). >But as for the idea of making a standard boolean type for C, I'd have to say >that this is going a bit too far, since it would make life difficult to the >many programmers who actually make good use of ints as booleans. I invoke Heuer's Law: Any feature is a bug unless it can be turned off. (The original example, I think, was the way the adm3a terminal would ring the bell whenever a character was printed in column 72. On *output*, fergodsake.) So leave out <bool.h>, and you continue to get ints. >Since most languages compile booleans to ints anyways, why not use that >extra space for your own purposes? On the other hand, why not let the compiler make use of that space by putting all the local Boolean objects into a single register? (Not hard, *if* the compiler's been told that it's dealing with Boolean rather than integer data!) Why should I have to do it myself by defining flag bits? Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint