I would suggest that bool NOT be an integer type. All conditional tests
should return bool and all conditional expressions should only accept
bools, not integers.
That would mean no casts (implicit or explicit) from one to the other.
The general idea is to prevent this classic bug:
int a,b;
if( a = b) ...
This returns an integer which is passed to the if. Some compilers
notice this and issue warnings, but that solution is not necessarily
reliable and it increases compiler complexity.
Making bool's and int's different types also reduces the number of
operators we need. The &&, ||, and ~ operators could all be deprecated:
bool & bool logical AND
bool | bool logical OR
!bool logical NOT
int & int bitwise AND
int | int bitwise OR
!int bitwise NOT
I suggest the & and | operators because they are shorter to type, and
the ! operator over the ~ operator because it is better known.

Your points are well taken. One of my problems with a separate bool type is
that a bool can have only two values, yet it is represented by a type that
can contain many values. It just never seems to feel right. -Walter
Russ Lewis wrote in message <3B7D5282.5AF7C365 deming-os.org>...

I would suggest that bool NOT be an integer type. All conditional tests
should return bool and all conditional expressions should only accept
bools, not integers.
That would mean no casts (implicit or explicit) from one to the other.
The general idea is to prevent this classic bug:
int a,b;
if( a = b) ...
This returns an integer which is passed to the if. Some compilers
notice this and issue warnings, but that solution is not necessarily
reliable and it increases compiler complexity.
Making bool's and int's different types also reduces the number of
operators we need. The &&, ||, and ~ operators could all be deprecated:
bool & bool logical AND
bool | bool logical OR
!bool logical NOT
int & int bitwise AND
int | int bitwise OR
!int bitwise NOT
I suggest the & and | operators because they are shorter to type, and
the ! operator over the ~ operator because it is better known.

Your points are well taken. One of my problems with a separate bool type is
that a bool can have only two values, yet it is represented by a type that
can contain many values. It just never seems to feel right. -Walter

Walter,
I would tend to agree with the original poster here. If the programmer really
cares about the non-zero value of a boolean value, then they're really looking
for an integral value anyhow. I don't know compiler theory all that well, but
I would think that if the compiler were aware of the intention of using a
boolean, that it could generate better assembly code as well. I think there is
a valuable semantic difference between the types, and the distinction can save
much pain in using the language. Add up the time that every programmer out
there spends at least once, and usually numerous times, in there life finding
the bug that the original poster mentioned, then multiply that by the potential
millions who could use / derive value from this spec.
What is the cost of having a seperate boolean value, aside from a few
characters in source files for the '== 0', and a relatively simple extra type
in compilers? Is there some other tradeoff that I'm missing here?
--
Ben Kuhn

Your points are well taken. One of my problems with a separate bool type is
that a bool can have only two values, yet it is represented by a type that
can contain many values. It just never seems to feel right. -Walter

Walter,
I would tend to agree with the original poster here. If the programmer really
cares about the non-zero value of a boolean value, then they're really looking
for an integral value anyhow. I don't know compiler theory all that well, but
I would think that if the compiler were aware of the intention of using a
boolean, that it could generate better assembly code as well. I think there is
a valuable semantic difference between the types, and the distinction can save
much pain in using the language. Add up the time that every programmer out
there spends at least once, and usually numerous times, in there life finding
the bug that the original poster mentioned, then multiply that by the potential
millions who could use / derive value from this spec.
What is the cost of having a seperate boolean value, aside from a few
characters in source files for the '== 0', and a relatively simple extra type
in compilers? Is there some other tradeoff that I'm missing here?

What I've seen is a lot of people who use this:
rc = DoStuff()
if(rc)
return rc;
Many of the people used to such tests would grumble to have to make it rc==0.
However, most of these tests, happily, are *far* better handled with
exceptions. :)

What is the cost of having a seperate boolean value, aside from a few
characters in source files for the '== 0', and a relatively simple extra

in compilers? Is there some other tradeoff that I'm missing here?

Sometimes there can be a penalty in the generated code, because !=0 values
would have to be converted to boolean, as in:
bool b = i ? 1 : 0;
There would also be confusion (I suspect) with the 'bit' type.

What is the cost of having a seperate boolean value, aside from a few
characters in source files for the '== 0', and a relatively simple extra

in compilers? Is there some other tradeoff that I'm missing here?

Sometimes there can be a penalty in the generated code, because !=0 values
would have to be converted to boolean, as in:
bool b = i ? 1 : 0;
There would also be confusion (I suspect) with the 'bit' type.

I do generate that conversion in my compiler Walter. It is specified in the
ANSI C specs, and I think is a good thing. The code generated in x86
instructions (supposing the result already in a register)
or register
setneq byte location
two instructions, not a big deal. Of course, sometimes there are other
sequences that get generated, but at most a few instructions. Not a big
deal, and you are sure that all booleans are either zero or one... This is a
conceptual simplification that is worth the few instructions. At 1GHZ now,
this doesn't matter much any more.

two instructions, not a big deal. Of course, sometimes there are other
sequences that get generated, but at most a few instructions. Not a big
deal, and you are sure that all booleans are either zero or one... This is

conceptual simplification that is worth the few instructions. At 1GHZ now,
this doesn't matter much any more.

I'll have to disagree that a few extra instructions are painless at 1GHz.
For example, when I turn my machine on the morning, I go off and get some
coffee, chat with friends, run errands, read the paper, and by the time I
get back it's almost at the logon prompt <g>.

Walter,
I would tend to agree with the original poster here. If the programmer

cares about the non-zero value of a boolean value, then they're really

for an integral value anyhow. I don't know compiler theory all that well,

I would think that if the compiler were aware of the intention of using a
boolean, that it could generate better assembly code as well. I think

a valuable semantic difference between the types, and the distinction can

much pain in using the language. Add up the time that every programmer

there spends at least once, and usually numerous times, in there life

the bug that the original poster mentioned, then multiply that by the

millions who could use / derive value from this spec.
What is the cost of having a seperate boolean value, aside from a few
characters in source files for the '== 0', and a relatively simple extra

in compilers? Is there some other tradeoff that I'm missing here?
--

Hi,
I think it has advantages and disadvantages;
maybe it's not such a big deal if bool is treated as an integer, as long as
the compiler generates proper warnings, like in the above mentioned (a=b)
case..
But I too tend to prefer the bool type to be treated in the more restrictive
way;
the ideal for me is bool can only be true/false 1/0 and no other value, rel
ops should return always boolean and if/while should expect boolean
expressions.
I think that the 0=false and other-than-zero = true approach of some
compilers can be misleading for the programmers (some at least :);
Example: suppose the programmer incidentally uses bitwise & instead of
logical && in the following case
bool MyFunction()
{
a is 0x55 nonzero, -> true
b is 0xAA nonzero, -> true
return a && b; // returns true
but...
return a & b; // returns false
}
perfectly ok for the compiler if integer/bool can be freely mixed, however
true and true = false is not very intuitive.
Also, each approach has some influence on the generated code;
for example if the compiler cannot assume false always = 0 and true always =
1, there are some cases in which it is forced to use normalization tricks,
(like SBB etc. on the x86) which would (could) be unnecessary with a
restrictive bool type. (it can also happen the other way around tho'!)
--Luigi

Your points are well taken. One of my problems with a separate bool type is
that a bool can have only two values, yet it is represented by a type that
can contain many values. It just never seems to feel right. -Walter

May I politely remark that you are taking an x86-centric view of the world
here? :-) For instance, consider IA-64. The IA-64 has 64 1-bit predicate
registers. These are real bools. Well, even in the x86 world, it's not a big
deal to allocate one bit per bool in a shared byte, and to have some hint in
your register/stack allocator to ensure that bools tend to be packed together.
Christophe

Your points are well taken. One of my problems with a separate bool type is
that a bool can have only two values, yet it is represented by a type that
can contain many values. It just never seems to feel right. -Walter
Russ Lewis wrote in message <3B7D5282.5AF7C365 deming-os.org>...

Well, you could define 0 as false, 255 as true, and the values in
between as values of maybe. That would use all the bits (maybe).
This would allow comparison to be defined, but what would be the results
of a branch? Take both branches on different processors? Flip a random
number generator?
Alternatively, a bool could be defined as a bit vector of length 8(?),
with the standard operations addressing the 0th element. Or maybe the
high bit. (Are those the same, or different?)
I'm not sure what value either of these would have. The bit vector
seems cheapest. The only additional operation needed if rotate, and
that's usually an assembler primitive.

Well, I can't offer any technical reasons but I agree with your feeling
here. I find the C style logical operator very powerful. Frankly I
wish you would add perl style 'until' and 'unless' structures as well as
the ability to have a statement followed by a loop or conditional
statement since I find it to be very expressive. I find these help make
intentions clearer in certain cases. I had no good technical reason for
that either so I head off asking.
In any case, I'm glad to see labeled breaks and continues, a redo might
be nice to avoid a goto, and I hope you keep the logical ops I know and
love. They allow me to say more meaningful things with less verbage.
Dan
Walter wrote:

Your points are well taken. One of my problems with a separate bool type is
that a bool can have only two values, yet it is represented by a type that
can contain many values. It just never seems to feel right. -Walter
Russ Lewis wrote in message <3B7D5282.5AF7C365 deming-os.org>...

I would suggest that bool NOT be an integer type. All conditional tests
should return bool and all conditional expressions should only accept
bools, not integers.
That would mean no casts (implicit or explicit) from one to the other.
The general idea is to prevent this classic bug:
int a,b;
if( a = b) ...
This returns an integer which is passed to the if. Some compilers
notice this and issue warnings, but that solution is not necessarily
reliable and it increases compiler complexity.
Making bool's and int's different types also reduces the number of
operators we need. The &&, ||, and ~ operators could all be deprecated:
bool & bool logical AND
bool | bool logical OR
!bool logical NOT
int & int bitwise AND
int | int bitwise OR
!int bitwise NOT
I suggest the & and | operators because they are shorter to type, and
the ! operator over the ~ operator because it is better known.

Well, I can't offer any technical reasons but I agree with your feeling
here. I find the C style logical operator very powerful. Frankly I
wish you would add perl style 'until' and 'unless' structures as well as
the ability to have a statement followed by a loop or conditional
statement since I find it to be very expressive. I find these help make
intentions clearer in certain cases. I had no good technical reason for
that either so I head off asking.

I'm a big fan of 'unless' & 'until' myself. From a compiler implementation
point of view, it's very cheap syntactical sugar but, as you suggest,
'unless (...)' can frequently express intent much more clearly than 'if
(!...)'

In any case, I'm glad to see labeled breaks and continues, a redo might
be nice to avoid a goto, and I hope you keep the logical ops I know and
love. They allow me to say more meaningful things with less verbage.

Your points are well taken. One of my problems with a separate bool type is
that a bool can have only two values, yet it is represented by a type that
can contain many values. It just never seems to feel right.

On many machines, quite a lot of the basic integer types are
represented using full registers, with superfluous bits. Why do you
have problems with that?
--
Florian Weimer Florian.Weimer RUS.Uni-Stuttgart.DE
University of Stuttgart http://cert.uni-stuttgart.de/
RUS-CERT +49-711-685-5973/fax +49-711-685-5898

On many machines, quite a lot of the basic integer types are
represented using full registers, with superfluous bits. Why do you
have problems with that?
--

Because the logistics of bool are different than the logistics of integer.
Integer has (usually) 2^32 individual values, each with their own unique
meaning. The concept of bool means that the value of the variable is either
"false" or "true". With an integer implementation, you change the concept
of the bool to "false" or "not false".
Represent a bool with individual bits either on or off, and you can have 8
bools take up 1 byte, instead of 8 bytes, easy to implement with D's built
in bit type and bit array type.
Just an issue of semantics. Proper semantics can help you "feel right" :)
-Brady

Because the logistics of bool are different than the logistics of integer.

Are they?

Integer has (usually) 2^32 individual values, each with their own
unique meaning. The concept of bool means that the value of the
variable is either "false" or "true". With an integer
implementation, you change the concept of the bool to "false" or
"not false".

Not necessarily. Sometimes it is useful not to consider
representation issues at all and think in terms of more abstract
operations on values.

Represent a bool with individual bits either on or off, and you can have 8
bools take up 1 byte, instead of 8 bytes, easy to implement with D's built
in bit type and bit array type.

Yes, of course, but I don't see the relevance of this for 'bool's.
This is a representation issue, and I think we were talking about the
semantics and the operations available for values of the 'bool' type.

Just an issue of semantics. Proper semantics can help you "feel
right" :)

Of course, you could make 'bool' an integer type, but please make it
distinct from the other integer types (no default implicit conversion,
for example).
--
Florian Weimer Florian.Weimer RUS.Uni-Stuttgart.DE
University of Stuttgart http://cert.uni-stuttgart.de/
RUS-CERT +49-711-685-5973/fax +49-711-685-5898

Yes, this elimenates several common errors often encountered in C
source code.

Making bool's and int's different types also reduces the number of
operators we need. The &&, ||, and ~ operators could all be deprecated:
bool & bool logical AND
bool | bool logical OR
!bool logical NOT

What about short-circuit evaluation? Perhaps this should be provided
by a non-overloadable operator.
--
Florian Weimer Florian.Weimer RUS.Uni-Stuttgart.DE
University of Stuttgart http://cert.uni-stuttgart.de/
RUS-CERT +49-711-685-5973/fax +49-711-685-5898

Yes, this elimenates several common errors often encountered in C
source code.

Making bool's and int's different types also reduces the number of
operators we need. The &&, ||, and ~ operators could all be deprecated:
bool & bool logical AND
bool | bool logical OR
!bool logical NOT

What about short-circuit evaluation? Perhaps this should be provided
by a non-overloadable operator.

What about short-circuit evaluation? Perhaps this should be provided
by a non-overloadable operator.

Short-circuit evaluation is still possible, provided that both sides of the
operator return bools.

IMHO, the '&' and '&&' distinction in C isn't clear enough to separate
both forms. You seem to suggest to remove any syntactic difference
between the two. I fear this has a negative effect on readability and
maintainability.
--
Florian Weimer Florian.Weimer RUS.Uni-Stuttgart.DE
University of Stuttgart http://cert.uni-stuttgart.de/
RUS-CERT +49-711-685-5973/fax +49-711-685-5898

What about short-circuit evaluation? Perhaps this should be provided
by a non-overloadable operator.

Short-circuit evaluation is still possible, provided that both sides of the
operator return bools.

IMHO, the '&' and '&&' distinction in C isn't clear enough to separate
both forms. You seem to suggest to remove any syntactic difference
between the two. I fear this has a negative effect on readability and
maintainability.

Sorry, I don't understand what you're getting at. Can you explain in more
detail?

Time to argue with myself (a bit).
I just was at a code review and saw people testing bit flags against a state
variable:
if(foo | INTERESTING_FLAG)
....
else if(bar | BORING_FLAG)
....
If we take my advice, this code becomes:
if(foo | INTERESTING_FLAG == INTERESTING_FLAG)
....
I *really* don't like the extra typing. Plus, it's much harder to read.
So, I pondered a bit, and I'm thinking that maybe we could use the 'in'
keyword. It would be as readable (or more) than the C version:
if(INTERESTING_FLAG in foo)
....
In the integer/integer context, in is just syntax sugar:
intA in intB
is expanded by the compiler to
((intA | intB) == intA)
which obviously returns bool.

Grimace...you're right, the code is wrong (needs to be an AND)...but no, it
won't always be true...if foo has bits set that are not part of
INTERESTING_FLAG, then it would be false...

I guess you mean:

if(foo & INTERESTING_FLAG == INTERESTING_FLAG)

Righto.

But you can also write it this way:

if(foo & INTERESTING_FLAG != 0)

resulting in the same, and is the same logic as the implizid C statement:
everything but zero is true, zero is false.

Double grimace...don't know why I didn't think of that. Wish I could say
that it was late at night when I posted, but it wasn't :(
Ok, so there is a faster way to do this than I said. Yours *is* much
cleaner.

Grimace...you're right, the code is wrong (needs to be an AND)...but no, it
won't always be true...if foo has bits set that are not part of
INTERESTING_FLAG, then it would be false...

I guess you mean:

if(foo & INTERESTING_FLAG == INTERESTING_FLAG)

Righto.

But you can also write it this way:

if(foo & INTERESTING_FLAG != 0)

resulting in the same, and is the same logic as the implizid C statement:
everything but zero is true, zero is false.

Double grimace...don't know why I didn't think of that. Wish I could say
that it was late at night when I posted, but it wasn't :(
Ok, so there is a faster way to do this than I said. Yours *is* much
cleaner.

Ack, got a problem here. I just realized that unless we use some funky
(perhaps confusing) rules, unifying && and & breaks some precedence rules.
Look at this code:
if(foo & INTERESTING_FLAG != 0 &
bar & BORING_FLAG != 0)
....
In old C syntax, & had high precedence, != had middle, and && had low. Thus,
the C test worked
if(foo & INTERESTING_FLAG != 0 &&
bar & BORING_FLAG != 0)
Theorhetically, it's not hard to tell the difference between the bool context
and the int context. But if you use bison to parse it, you have a problem.
How onerous is it, do you think, to require the syntax to be:
if( (foo & INTERESTING_FLAG) &
(bar & BORING_FLAG))
I think that that would be bug-prone, unfortunately. I still like the theory
of unifying the operators...anybody have a good syntax for it?

Ack, got a problem here. I just realized that unless we use some funky
(perhaps confusing) rules, unifying && and & breaks some precedence rules.
Look at this code:
if(foo & INTERESTING_FLAG != 0 &
bar & BORING_FLAG != 0)
....
In old C syntax, & had high precedence, != had middle, and && had low.
Thus, the C test worked
if(foo & INTERESTING_FLAG != 0 &&
bar & BORING_FLAG != 0)
Theorhetically, it's not hard to tell the difference between the bool
context
and the int context. But if you use bison to parse it, you have a
problem.
How onerous is it, do you think, to require the syntax to be:
if( (foo & INTERESTING_FLAG) &
(bar & BORING_FLAG))
I think that that would be bug-prone, unfortunately. I still like the
theory of unifying the operators...anybody have a good syntax for it?

Pascal had exactly this problem, AND and OR where both binary and boolean
operators, and additionally to their sense of being binary they had higher
binding than the equal operators. (remember then single = means equals in
pascal)
IF a = 1 AND b = 2 THEN
BEGIN
foo;
END
Any pascal user will scream and say it has to be written as:
IF (a = 1) AND (b = 2) THEN
Or the compiler will implicitly see following:
IF (a = (1 AND b)) = 2 THEN
something very different :o)
I started learing programming with pascal, and later switched to C. And
hence after all these years I'm still most times using these brackets even
in C, altough it wouldn't need them, it's beeing a burned child. Just the
same thing goes the other side, everytime i've now written a single equal
sign meaning a compare my whole body cramps :o)
After actually trying the alternatives in practice one has to admit that a
few C ideas weren't so bad after all :o) Okay c has still a lot of
braindead quircks, but it's the only one that seems to satisfy industry :/
I for me have keeped the && and || parameters, in the sense of leaving the
predecnce of all operator exactly as C. After having programmed both Pascal
and C, having different precedence rules, I'm even after years not even
having looked at pascal still unsure about their precedence, I don't want
also to 'hurt' others like this :o)
Okay once you've coded a parser, you know them better :o) For C once you've
looked at a parser for it, you realize what for braindead
constructs the C grammar actually allows, no sane person could ever think
of :o) Like anonymous structs in functions or
void hallo (struct a {int i} b);
Okay but don't nail me if it's really correct C, just guessed it.
Hmm how about:
void (*)(void) (* a)(int);
Should be a function pointer to a function returning a function pointer.
I don't know about C++, but the gcc guys moan constantly about it, but I
guess Walter could tell you more about C++ parsing :o)
- Axel

I for me have keeped the && and || parameters, in the sense of leaving the
predecnce of all operator exactly as C. After having programmed both Pascal
and C, having different precedence rules, I'm even after years not even
having looked at pascal still unsure about their precedence, I don't want
also to 'hurt' others like this :o)

It's important to keep the same precedence rules as C. Nothing will screw
programmers up more than to subtly shift them.

In article <9p29du$233h$1 digitaldaemon.com>,
"Walter" <walter digitalmars.com> writes:
|>
|> Axel Kittenberger wrote in message <9n5vfr$2067$1 digitaldaemon.com>...
|> >I for me have keeped the && and || parameters, in the sense of leaving the
|> >predecnce of all operator exactly as C. After having programmed both Pascal
|> >and C, having different precedence rules, I'm even after years not even
|> >having looked at pascal still unsure about their precedence, I don't want
|> >also to 'hurt' others like this :o)
|>
|> It's important to keep the same precedence rules as C. Nothing will screw
|> programmers up more than to subtly shift them.
I agree, but what about not permitting this:
if ( a < b && c < d || b < e && istrue(f) || isfalse(g)) {
// guess you don't know when you go by here
exit(2);
}
Precedence and associativity say it is the same as:
if ( (a < b && c < d) || (b < e && istrue(f)) || isfalse(g)) {
exit(2);
}
gcc suggests to use explicit parenthesis aound && within ||, and
I think this should be mandatory for D.
Ciao

In article <9p29du$233h$1 digitaldaemon.com>,
"Walter" <walter digitalmars.com> writes:
gcc suggests to use explicit parenthesis aound && within ||, and I think
this should be mandatory for D.

I agree. Some C style guides recommend doing this sort of thing. Rather
than changing the precedence, we can just remove it.

Funny, I always thought that the precedence of boolean operators were
as well understood and standard as those of addition and
multiplication. Should we require explicit parens around all infix and
unary operations?
I had AND taught to me as boolean multiplication and OR taught as
boolean addition. XOR and implication was always a bit of gray area,
but AND and OR were well defined. I'd hate to clutter the expressions
in the cases were it isn't really needed.
Dan

Funny, I always thought that the precedence of boolean operators were
as well understood and standard as those of addition and multiplication.
Should we require explicit parens around all infix and unary
operations?
I had AND taught to me as boolean multiplication and OR taught as
boolean addition. XOR and implication was always a bit of gray area,
but AND and OR were well defined. I'd hate to clutter the expressions
in the cases were it isn't really needed.

In article <9p29du$233h$1 digitaldaemon.com>, "Walter"
<walter digitalmars.com> writes:
gcc suggests to use explicit parenthesis aound && within
||, and I think this should be mandatory for D.

thing. Rather than changing the precedence, we can
just remove it.

Funny, I always thought that the precedence of boolean
operators were as well understood and standard as those of
addition and multiplication. Should we require explicit
parens around all infix and unary operations? I had AND
taught to me as boolean multiplication and OR taught as boolean
addition. XOR and implication was always a bit of gray
area, but AND and OR were well defined. I'd hate to
clutter the expressions in the cases were it isn't really
needed.
Dan

the same precedence, and that parenthesis was always required if
both operations were preformed.