468,469 Members | 1,972 Online

"a < b < c" not the same as "(a < b) && (b < c)"?

In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

e.g:

for a = 0, b = 3 and c = 2:

a < b < c = 1
(a < b) && (b < c) = 0

when typed in C.

Nov 15 '05 #1
72 3514

"Paminu" <ja******@asd.com> wrote in message
news:di**********@news.net.uni-c.dk...
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

e.g:

for a = 0, b = 3 and c = 2:

a < b < c = 1
(a < b) && (b < c) = 0

when typed in C.

(0 < 0) && (0 < 0)

false && false = false according to the truth table for logical AND

Nov 15 '05 #2

"pemo" <us************@gmail.com> wrote in message
news:di**********@news.ox.ac.uk...

"Paminu" <ja******@asd.com> wrote in message
news:di**********@news.net.uni-c.dk...
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

e.g:

for a = 0, b = 3 and c = 2:

a < b < c = 1
(a < b) && (b < c) = 0

when typed in C.

(0 < 0) && (0 < 0)

false && false = false according to the truth table for logical AND

Oops - sorry - bit too quick there!

(0 < 3) && (3 < 2)

true && false = false - logical AND requires both operands to be true to get
a true result

Nov 15 '05 #3
pemo wrote:

"pemo" <us************@gmail.com> wrote in message
news:di**********@news.ox.ac.uk...

"Paminu" <ja******@asd.com> wrote in message
news:di**********@news.net.uni-c.dk...
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

e.g:

for a = 0, b = 3 and c = 2:

a < b < c = 1
(a < b) && (b < c) = 0

when typed in C.

(0 < 0) && (0 < 0)

false && false = false according to the truth table for logical AND

Oops - sorry - bit too quick there!

(0 < 3) && (3 < 2)

true && false = false - logical AND requires both operands to be true to
get a true result

0 < 3 < 2

how is that evaluated?

Nov 15 '05 #4

"Paminu" <ja******@asd.com> wrote in message
news:di**********@news.net.uni-c.dk...
pemo wrote:

<snip>

0 < 3 < 2

how is that evaluated?

Associativity - what happens when operators have the same precedence.

< = left to right

So, you've got ((0 < 3) < 2)

which resolves to (1 < 2)

1 [true] (as 0 IS less than 3)

which resolves to 1 (true)
Nov 15 '05 #5
I think the problem is the order is from left to right,
the value of a<b is TRUE, which equal to 1, then 1 < c is also TRUE, so
the value of a<b<c is TRUE;

but in the (a<b)&&(b<c)
a<b is TRUE ,1
b<c is FALSE, 0
so they equal to 1&&0 ,means 0

Nov 15 '05 #6
Paminu wrote:
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

e.g:

for a = 0, b = 3 and c = 2:

a < b < c = 1
(a < b) && (b < c) = 0

when typed in C.

Remember that C has no boolean type. The (binary) "<" operator returns 0
(false) or 1 (true), so `0 < 3' is 1 and `1 < 2' is 1.
August
Nov 15 '05 #7
Paminu wrote:

In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

Because
(a < b < c)
means
(((a < b) != 0) < c)

--
pete
Nov 15 '05 #8
pete wrote:
Paminu wrote:
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

Because
(a < b < c)
means
(((a < b) != 0) < c)

....or

((((a < b) != 0) < c) != 0)

or why not

(((((a < b) != 0) < c) != 0) != 0)

and so on... ;-)
August
Nov 15 '05 #9
August Karlstrom <fu********@comhem.se> writes:
[...]
Remember that C has no boolean type. The (binary) "<" operator returns
0 (false) or 1 (true), so `0 < 3' is 1 and `1 < 2' is 1.

C has had a boolean type for 6 years; C99 added _Bool. It's true that
support for C99 is not yet universal, though.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #10
Keith Thompson wrote:
August Karlstrom <fu********@comhem.se> writes:
[...]
Remember that C has no boolean type. The (binary) "<" operator returns
0 (false) or 1 (true), so `0 < 3' is 1 and `1 < 2' is 1.

C has had a boolean type for 6 years; C99 added _Bool. It's true that
support for C99 is not yet universal, though.

Your second sentence sort-of undoes the first completely, you know.

Next they'll be telling me C++ compilers have started to support the
"export" keyword... though that is completely not comparable, of course. :-)

S.
Nov 15 '05 #11
Skarmander <in*****@dontmailme.com> writes:
Keith Thompson wrote:
August Karlstrom <fu********@comhem.se> writes:
[...]
Remember that C has no boolean type. The (binary) "<" operator returns
0 (false) or 1 (true), so `0 < 3' is 1 and `1 < 2' is 1.

C has had a boolean type for 6 years; C99 added _Bool. It's true
that
support for C99 is not yet universal, though.

Your second sentence sort-of undoes the first completely, you know.

Um, no. There's a big difference between "not yet univeral" and
"nonexistent" -- and, strictly speaking, C99 *is* the current C
standard. Most, but not all, compilers I currently have access to do
support _Bool, even if they don't fully support C99.

Saying that C has no boolean type is comparable to saying in, say,
1992 that C has no function prototypes (adjust the year to taste). It
was true that support for prototypes was not universal, but they had
become part of the language.

Most discussions of C99 features to need to be qualified with a
statement that they're not universally supported, but it doesn't make
sense to ignore C99 completely.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #12
Keith Thompson wrote:
August Karlstrom <fu********@comhem.se> writes:
[...]
Remember that C has no boolean type. The (binary) "<" operator returns
0 (false) or 1 (true), so `0 < 3' is 1 and `1 < 2' is 1.

C has had a boolean type for 6 years; C99 added _Bool. It's true that
support for C99 is not yet universal, though.

OK, let me rephrase that: C has no native (primitive) boolean type. If
it had then `a < b < c' would not be a valid expression.
August

Nov 15 '05 #13
August Karlstrom wrote:

pete wrote:
Paminu wrote:
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

Because
(a < b < c)
means
(((a < b) != 0) < c)

...or

((((a < b) != 0) < c) != 0)

or why not

(((((a < b) != 0) < c) != 0) != 0)

and so on... ;-)

The nature of the question was something like
"Why does the same word mean different things,
in different languages?"

Things like
i = i + 1
are never going to make sense,
if Paminu doesn't realise that C is a language,
and that symbols that he knows from mathematics
may have different meanings in C.

--
pete
Nov 15 '05 #14
Keith Thompson wrote:
Skarmander <in*****@dontmailme.com> writes:
Keith Thompson wrote:
August Karlstrom <fu********@comhem.se> writes:
[...]
Remember that C has no boolean type. The (binary) "<" operator returns
0 (false) or 1 (true), so `0 < 3' is 1 and `1 < 2' is 1.

C has had a boolean type for 6 years; C99 added _Bool. It's true
that
support for C99 is not yet universal, though.

Your second sentence sort-of undoes the first completely, you know.

Um, no. There's a big difference between "not yet univeral" and
"nonexistent" -- and, strictly speaking, C99 *is* the current C
standard. Most, but not all, compilers I currently have access to do
support _Bool, even if they don't fully support C99.

OK. Granted. There's a big difference. That nobody is noticing in
practice. Yet. But I can't deny you're right.
Saying that C has no boolean type is comparable to saying in, say,
1992 that C has no function prototypes (adjust the year to taste). It
was true that support for prototypes was not universal, but they had
become part of the language.

Most discussions of C99 features to need to be qualified with a
statement that they're not universally supported, but it doesn't make
sense to ignore C99 completely.

Yeah, yeah. Let's come back and reconvene in, say, 8 years, and count
what percentage of C programs are C99 as opposed to C89. For now,
mentioning C99's features, while instructive and certainly topical,
remains at best a career investment.

I know the exact same inertia happened with C89 and C++ (although
frankly C++ was an extreme example because they kept tweaking the
language) and eventually full support for those became ubiquitous. But I
for one get impatient with so much inertia, and when I see the claim
that support is "not yet universal", I think "is it understatement time

S.
Nov 15 '05 #15
In article <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
August Karlstrom <fu********@comhem.se> writes:
[...]
Remember that C has no boolean type. The (binary) "<" operator returns
0 (false) or 1 (true), so `0 < 3' is 1 and `1 < 2' is 1.

C has had a boolean type for 6 years; C99 added _Bool. It's true that
support for C99 is not yet universal, though.

But that is not really relevant. The operators will not return the boolean
values for a long time. And once they return it: a < b < c becomes
illegal I think.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 15 '05 #16
In article <dw*******************@newsb.telia.net> August Karlstrom <fu********@comhem.se> writes:
Keith Thompson wrote:
August Karlstrom <fu********@comhem.se> writes:
[...]
Remember that C has no boolean type. The (binary) "<" operator returns
0 (false) or 1 (true), so `0 < 3' is 1 and `1 < 2' is 1.

C has had a boolean type for 6 years; C99 added _Bool. It's true that
support for C99 is not yet universal, though.

OK, let me rephrase that: C has no native (primitive) boolean type. If
it had then `a < b < c' would not be a valid expression.

operators depending on the type returned would be needed. This can be
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 15 '05 #17
August Karlstrom <fu********@comhem.se> writes:
Keith Thompson wrote:
August Karlstrom <fu********@comhem.se> writes:
[...]
Remember that C has no boolean type. The (binary) "<" operator returns
0 (false) or 1 (true), so `0 < 3' is 1 and `1 < 2' is 1. C has had a boolean type for 6 years; C99 added _Bool. It's true
that
support for C99 is not yet universal, though.

OK, let me rephrase that: C has no native (primitive) boolean type.

Yes, it does. It's called _Bool (or bool with "#include <stdbool.h>").
If it had then `a < b < c' would not be a valid expression.

That doesn't follow. Even if the "<" operator yielded a value of type
_Bool rather than int, the expression "a < b" would yield either true
or false, and the comparison "true < c" or "false < c" would still be
legal.

C's (more precisely, C99's) native boolean type happens to be an
integer type, and integer type can be freely and implicitly converted
to each other.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #18
In article <di**********@news.net.uni-c.dk>, Paminu <ja******@asd.com>
wrote:
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

e.g:

for a = 0, b = 3 and c = 2:

a < b < c = 1
(a < b) && (b < c) = 0

when typed in C.

Because that's the way the syntax is defined. Not very useful. Just for
fun, try defining a grammar that doesn't allow a < b < c (that's easy),
then try defining a grammar that allows expressions like a <= b < c == d
<= e but not a <= b > c, then try defining the semantics like in
mathematics. It's fun.
Nov 15 '05 #19
"Paminu" <ja******@asd.com> wrote in message news:di**********@news.net.uni-c.dk...
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

e.g:

for a = 0, b = 3 and c = 2:

a < b < c = 1
(a < b) && (b < c) = 0

when typed in C.

((a < b ? b : a) < c)
Nov 15 '05 #20
Keith Thompson wrote:
And gcc, probably the most popular C
compiler out there, supports *most* of C99, including _Bool.

It's strange that gcc (3.3.5) accepts _Bool declarations even when
compiled with the option `-std=c89':

\$ cat test.c
#include <stdio.h>

int main(void)
{
_Bool b = 1;

if (b) puts("b holds true.");
return 0;
}
\$ gcc -ansi -pedantic -std=c89 -Wall -o test test.c
\$
August
Nov 15 '05 #21
August Karlstrom <fu********@comhem.se> writes:
Keith Thompson wrote:
August Karlstrom <fu********@comhem.se> writes:
OK, let me rephrase that: C has no native (primitive) boolean type. Yes, it does. It's called _Bool (or bool with "#include
<stdbool.h>").

OK, you're right, sorry. The existence of the header file has made me
think it's not a native type. So _Bool is just an integer type that
can hold two values: 0 or 1, and it's called _Bool just to minimize
the risk of breaking existing programs, right?

Right. It can almost certainly hold values other than 0 or 1, but
since conversion from any integer type to _Bool always yields a result
of 0 or 1, it's difficult to store any other value in a _Bool object.
A more extreme
defensive approach would be to call it __BoOl or something ;-)

That's not necessary, since _Bool is already in the reserved namespace
(as are _Complex and _Imaginary). Any C90 program using _Bool is in
trouble anyway.
C's (more precisely, C99's) native boolean type happens to be an
integer type, and integer type can be freely and implicitly converted
to each other.

...and that's why expressions such as `a < b < c' has the strange
(unexpected) semantics.

The semantics aren't strange at all *if* you look at them as being
built up from the semantics of the individual operators. "a + b + c"
is equivalent to "(a + b) + c". "a - b - c" is equivalent to
"(a - b) - c". The fact that the same rule applies to "a < b < c"
looks strange only because of the rather odd shorthand used in
mathematics. Programming languages tend to treat true/false values as
ordinary values; mathematics often treats them specially. The
approach used in programming languages is actually more uniform.

<OT>
Even in languages in which the native boolean type is non-numeric,
"a < b < c" tends not to mean what it means in mathematics. For
example, in Pascal the type Boolean is a special enumeration type (not
numeric) with values False and True and the relationship False < True.
The expression "a < b < c" is valid only if c is of type Boolean; the
result is equivalent to "(a < b) < c", and is either False or True.
</OT>

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #22
In article <ch*********************************@slb-newsm1.svr.pol.co.uk> Christian Bau <ch***********@cbau.freeserve.co.uk> writes:
Because that's the way the syntax is defined. Not very useful. Just for
fun, try defining a grammar that doesn't allow a < b < c (that's easy),
then try defining a grammar that allows expressions like a <= b < c == d
<= e but not a <= b > c, then try defining the semantics like in
mathematics. It's fun.

Why should "a <= b > c" be disallowed? It is clear what it means. And
indeed, in Ada it is easy to allow all those expressions. The only
problem (I see) is "a < (b < c)", but indeed, I have no idea what it
means.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 15 '05 #23
In article <DK***************@newssvr29.news.prodigy.net> "Keyser Soze" <no******@nothere.com> writes:
"Paminu" <ja******@asd.com> wrote in message news:di**********@news.net.uni-c.dk... ....
(a < b) && (b < c)

would be described as:

a < b < c

.... ((a < b ? b : a) < c)

No, in mathemarics that is not equivalent. Consider a < c, b < c and b < a.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 15 '05 #24
August Karlstrom <fu********@comhem.se> writes:
Keith Thompson wrote:
And gcc, probably the most popular C
compiler out there, supports *most* of C99, including _Bool.

It's strange that gcc (3.3.5) accepts _Bool declarations even when
compiled with the option `-std=c89':

_Bool is a valid extension to C89, because it cannot appear in
any strictly conforming C89 program.
--
Ben Pfaff
email: bl*@cs.stanford.edu
web: http://benpfaff.org
Nov 15 '05 #25

In article <ch*********************************@slb-newsm1.svr.pol.co.uk>, Christian Bau <ch***********@cbau.freeserve.co.uk> writes:

Because that's the way the syntax is defined. Not very useful. Just for
fun, try defining a grammar that doesn't allow a < b < c (that's easy),
then try defining a grammar that allows expressions like a <= b < c == d
<= e but not a <= b > c, then try defining the semantics like in
mathematics. It's fun.

In COBOL, Land of the Ad Hoc Grammar, you can use Abbreviated
Combined Relation Conditions, for example:

if b > a and < c

for the equivalent of the mathematical a < b < c. The standard (ISO
1989:2002 8.8.4.2.4) cautions against using NOT in ACRCs, as it may
lead to "results that are not intuitive". Their first example:

a > b AND NOT < c OR d means ((a > b) AND (a NOT < c)) OR (a NOT < d)

demonstrates nicely why too much syntatic sugar can cause decay.

Read more about it in ISO 1989:2002, which is a mere 879 pages.

--
Michael Wojcik mi************@microfocus.com

Any average educated person can turn out competent verse. -- W. H. Auden
Nov 15 '05 #26

"Dik T. Winter" <Di********@cwi.nl> wrote in message news:Io********@cwi.nl...
In article <DK***************@newssvr29.news.prodigy.net> "Keyser Soze" <no******@nothere.com> writes:
> "Paminu" <ja******@asd.com> wrote in message news:di**********@news.net.uni-c.dk...

...
> > (a < b) && (b < c)
> >
> > would be described as:
> >
> > a < b < c

...
> ((a < b ? b : a) < c)

No, in mathemarics that is not equivalent. Consider a < c, b < c and b < a.

Yes a problem.

What about: ((a < b ? b : c) < c) ?
Nov 15 '05 #27
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
The semantics aren't strange at all *if* you look at them as being
built up from the semantics of the individual operators. "a + b + c"
is equivalent to "(a + b) + c". "a - b - c" is equivalent to
"(a - b) - c". The fact that the same rule applies to "a < b < c"
looks strange only because of the rather odd shorthand used in
mathematics. Programming languages tend to treat true/false values as
ordinary values; mathematics often treats them specially. The
approach used in programming languages is actually more uniform.

<OT>
Even in languages in which the native boolean type is non-numeric,
"a < b < c" tends not to mean what it means in mathematics. For
example, in Pascal the type Boolean is a special enumeration type (not
numeric) with values False and True and the relationship False < True.
The expression "a < b < c" is valid only if c is of type Boolean; the
result is equivalent to "(a < b) < c", and is either False or True.
</OT>

That's because the particular way the semantics is defined in C. It
could have been defined differently, for example: In a sequence "a +/- b
+/- c +/- d..." first all the operands are evaluated; if no operand has
pointer type, then all are converted to a common type using the usual
arithmetic promotions, then they are added in an unspecified order. Some
further tricky semantics is needed if any operands are pointers.

That would allow compilers to compute a + b + c as (a + b) + c or a + (b
+ c), whatever is more efficient; explicit brackets can be used to force
evaluation order. Likewise, "a <relop> b <relop> c <relop> d ..." could
have been defined in the mathematical way.
Nov 15 '05 #28

Paminu wrote:
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

In maths the two exressions/conditions are said to be "equivalent" -
but not "EQUAL".

They are equivalent in 'C' also - when you check for their equivalance.

Nov 15 '05 #29
sudhz wrote:

Paminu wrote:
In math this expression:

(a < b) && (b < c)

would be described as:

a < b < c

But why is it that in C these two expressions evaluate to something
different for the same values of a, b and c?

In maths the two exressions/conditions are said to be "equivalent" -
but not "EQUAL".

They are equivalent in 'C' also
- when you check for their equivalance.

a < b < c
is true when c is 2 and false when c is 0.

(a < b) && (b < c)
always depends on the value of b and at least one other variable.

--
pete
Nov 15 '05 #30
Ben Pfaff wrote:
August Karlstrom <fu********@comhem.se> writes:

Keith Thompson wrote:
And gcc, probably the most popular C
compiler out there, supports *most* of C99, including _Bool.

It's strange that gcc (3.3.5) accepts _Bool declarations even when
compiled with the option `-std=c89':

_Bool is a valid extension to C89, because it cannot appear in
any strictly conforming C89 program.

Yes. It is unfortunate, though, that -std=c89 -pedantic -Wall is not
enough coercion to make GCC warn that using reserved identifiers like
_Bool is specifically undefined behaviour according to the standard. It
wouldn't be too hard to detect, I would think.

C89 4.8.9 "All external identifiers declared in any of the headers are
reserved, whether or not the associated header is included. All
external identifiers that begin with an underscore are reserved. All
other identifiers that begin with an underscore and either an
upper-case letter or another underscore are reserved. If the program
defines an external identifier with the same name as a reserved
external identifier, even in a semantically equivalent form, the
behavior is undefined."

--
Simon.
Nov 15 '05 #31
August Karlstrom <fu********@comhem.se> writes:
Keith Thompson wrote:
August Karlstrom <fu********@comhem.se> writes:
OK, let me rephrase that: C has no native (primitive) boolean type.

Yes, it does. It's called _Bool (or bool with "#include <stdbool.h>").

OK, you're right, sorry. The existence of the header file has made me
think it's not a native type. So _Bool is just an integer type that can
hold two values: 0 or 1, and it's called _Bool just to minimize the risk
of breaking existing programs, right?

The type _Bool is an integer type that can hold only two
values, those being 0 and 1. However, it's different
from other integer types in some important ways:

1. Assigning a zero value to a _Bool results in 0, and
assigning any non-zero value to a _Bool results in 1.
(Same for conversion.) No other integer type behaves
this way (in all implementations).

2. It's always legal to assign or convert a pointer
value to a _Bool.

In some sense the reason for _Bool is to have a type for
a variable that can capture exactly the value of a
control expression as would be used in an 'if', 'while'
or 'for'.
Nov 15 '05 #32
Tim Rentsch wrote:
[...]
In some sense the reason for _Bool is to have a type for
a variable that can capture exactly the value of a
control expression as would be used in an 'if', 'while'
or 'for'.

Interesting -- in other words, converting a value to _Bool behaves
exactly as if the '!' (logical not) operator was applied twice.

--
Simon.
Nov 15 '05 #33
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
August Karlstrom <fu********@comhem.se> writes:
Keith Thompson wrote:
> August Karlstrom <fu********@comhem.se> writes:
>>OK, let me rephrase that: C has no native (primitive) boolean type.
>
> Yes, it does. It's called _Bool (or bool with "#include <stdbool.h>").
OK, you're right, sorry. The existence of the header file has made me
think it's not a native type. So _Bool is just an integer type that can
hold two values: 0 or 1, and it's called _Bool just to minimize the risk
of breaking existing programs, right?

The type _Bool is an integer type that can hold only two
values, those being 0 and 1. However, it's different
from other integer types in some important ways:

1. Assigning a zero value to a _Bool results in 0, and
assigning any non-zero value to a _Bool results in 1.
(Same for conversion.) No other integer type behaves
this way (in all implementations).

It's all about conversion. The only way to assign a non-zero value to
a _Bool is to convert it to _Bool (unless it's already of type _Bool).
The conversion rules say that the result is always 0 or 1.
2. It's always legal to assign or convert a pointer
value to a _Bool.
I was about to disagree. Fortunately, I looked it up first; you can
assign a pointer value directly to a _Bool. Interesting.
In some sense the reason for _Bool is to have a type for
a variable that can capture exactly the value of a
control expression as would be used in an 'if', 'while'
or 'for'.

Yup.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #34
Keith Thompson <ks***@mib.org> wrote:
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
August Karlstrom <fu********@comhem.se> writes:
....
So _Bool is just an integer type that can
hold two values: 0 or 1, and it's called _Bool just to minimize the risk
of breaking existing programs, right?

The type _Bool is an integer type that can hold only two
values, those being 0 and 1. However, it's different
from other integer types in some important ways:

1. Assigning a zero value to a _Bool results in 0, and
assigning any non-zero value to a _Bool results in 1.
(Same for conversion.) No other integer type behaves
this way (in all implementations).

It's all about conversion. The only way to assign a non-zero value to
a _Bool is to convert it to _Bool (unless it's already of type _Bool).
The conversion rules say that the result is always 0 or 1.

# [#2] An object declared as type _Bool is large enough to
# store the values 0 and 1.

Doesn't that mean that _Bool _might_ hold other values as well?
The only method of obtaining such other value that comes to my mind
would be by reinterpreting bytes (eg. in a union, however such program
would not be s.c.).

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 15 '05 #35
Keith Thompson <ks***@mib.org> writes:
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
August Karlstrom <fu********@comhem.se> writes:
Keith Thompson wrote:
> August Karlstrom <fu********@comhem.se> writes:
>>OK, let me rephrase that: C has no native (primitive) boolean type.
>
> Yes, it does. It's called _Bool (or bool with "#include <stdbool.h>").

OK, you're right, sorry. The existence of the header file has made me
think it's not a native type. So _Bool is just an integer type that can
hold two values: 0 or 1, and it's called _Bool just to minimize the risk
of breaking existing programs, right?

The type _Bool is an integer type that can hold only two
values, those being 0 and 1. However, it's different
from other integer types in some important ways:

1. Assigning a zero value to a _Bool results in 0, and
assigning any non-zero value to a _Bool results in 1.
(Same for conversion.) No other integer type behaves
this way (in all implementations).

It's all about conversion. The only way to assign a non-zero value to
a _Bool is to convert it to _Bool (unless it's already of type _Bool).
The conversion rules say that the result is always 0 or 1.

Yes, but it's not only that the result is always 0 or 1.
An unsigned int bitfield of length one always holds either
0 or 1. But only _Bool maps any non-zero value to 1 and
only zero values to 0. There are conversions going on
in both cases (of bitfield and _Bool), but the conversion
rules for _Bool are different from those of any other
integer type.
Nov 15 '05 #36
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
Keith Thompson <ks***@mib.org> writes:
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
> August Karlstrom <fu********@comhem.se> writes:
>> Keith Thompson wrote:
>> > August Karlstrom <fu********@comhem.se> writes:
>> >>OK, let me rephrase that: C has no native (primitive) boolean type.
>> >
>> > Yes, it does. It's called _Bool (or bool with "#include <stdbool.h>").
>>
>> OK, you're right, sorry. The existence of the header file has made me
>> think it's not a native type. So _Bool is just an integer type that can
>> hold two values: 0 or 1, and it's called _Bool just to minimize the risk
>> of breaking existing programs, right?
>
> The type _Bool is an integer type that can hold only two
> values, those being 0 and 1. However, it's different
> from other integer types in some important ways:
>
> 1. Assigning a zero value to a _Bool results in 0, and
> assigning any non-zero value to a _Bool results in 1.
> (Same for conversion.) No other integer type behaves
> this way (in all implementations).

It's all about conversion. The only way to assign a non-zero value to
a _Bool is to convert it to _Bool (unless it's already of type _Bool).
The conversion rules say that the result is always 0 or 1.

Yes, but it's not only that the result is always 0 or 1.
An unsigned int bitfield of length one always holds either
0 or 1. But only _Bool maps any non-zero value to 1 and
only zero values to 0. There are conversions going on
in both cases (of bitfield and _Bool), but the conversion
rules for _Bool are different from those of any other
integer type.

Yes, well, if it weren't unique there wouldn't be much point in having
it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #37
"pemo" <us************@gmail.com> wrote in message
news:di**********@news.ox.ac.uk...

"Paminu" <ja******@asd.com> wrote in message
news:di**********@news.net.uni-c.dk...
pemo wrote:

<snip>

0 < 3 < 2
how is that evaluated?

Associativity - what happens when operators have the same precedence.
< = left to right

So, you've got ((0 < 3) < 2)
which resolves to (1 < 2)
1 [true] (as 0 IS less than 3)

Only for relatively small values of zero...
which resolves to 1 (true)

Couldn't TRUE be an arbitrary number in C? Say, 42? I know we've
discussed NULL being something other than zero, or located at zero, and
I wonder if TRUE and FALSE can be anything other than zero and one? Of
course, it would not be so on most machines you are likely to run
across, but it is all about the Standard, not practice, in c.l.c!

Here is a chance for Keith T to reply to a Mabden post with something
useful! ;-)

--
Mabden
Nov 15 '05 #38
"Mabden" <mabden@sbc_global.net> writes:
[...]
Couldn't TRUE be an arbitrary number in C? Say, 42? I know we've
discussed NULL being something other than zero, or located at zero, and
I wonder if TRUE and FALSE can be anything other than zero and one? Of
course, it would not be so on most machines you are likely to run
across, but it is all about the Standard, not practice, in c.l.c!

Read section 9 of the C FAQ, "Boolean Expressions and Variables".
(It hasn't yet been updated to reflect the changes in C99.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #39
Mabden wrote:
"pemo" <us************@gmail.com> wrote in message
news:di**********@news.ox.ac.uk...
"Paminu" <ja******@asd.com> wrote in message
news:di**********@news.net.uni-c.dk...
pemo wrote:

<snip>
0 < 3 < 2
how is that evaluated?

Associativity - what happens when operators have the same precedence.
< = left to right

So, you've got ((0 < 3) < 2)
which resolves to (1 < 2)
1 [true] (as 0 IS less than 3)

Only for relatively small values of zero...

Far to old a joke to be funny.
which resolves to 1 (true)

Couldn't TRUE be an arbitrary number in C? Say, 42?

The C standard defines the result as being 1, therefore you will not get
any other result in C. This has been stated here many times in the past
and will be covered in any basic C text book worth having.
I know we've
discussed NULL being something other than zero, or located at zero, and
I wonder if TRUE and FALSE can be anything other than zero and one? Of
course, it would not be so on most machines you are likely to run
across, but it is all about the Standard, not practice, in c.l.c!
Any value other than 0 will act as true, but you will only ever obtain
10 or 1 from expressions that yeald a boolean result. Note that not all
standard functions that you might expect to return a boolean result do so.
Here is a chance for Keith T to reply to a Mabden post with something
useful! ;-)

It is very rare for Keith's responses to not be useful. Since he is a
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #40
Flash Gordon <sp**@flash-gordon.me.uk> writes:
[...]
Any value other than 0 will act as true, but you will only ever obtain
10 or 1 from expressions that yeald a boolean result. Note that not ------- all standard functions that you might expect to return a boolean
result do so.

Presumably that was a typo for "0 or 1".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #41
Keith Thompson wrote:
Flash Gordon <sp**@flash-gordon.me.uk> writes:
[...]
Any value other than 0 will act as true, but you will only ever obtain
10 or 1 from expressions that yeald a boolean result. Note that not

-------
all standard functions that you might expect to return a boolean
result do so.

Presumably that was a typo for "0 or 1".

Oops. Yes.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #42
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
I was about to disagree. Fortunately, I looked it up first; you can
assign a pointer value directly to a _Bool. Interesting.

What does that mean? Assign the pointer to a _Bool or the value pointed
at to a _Bool? The former seems nonsensical, the later seems obvious
(why _wouldn't_ you be able to assign the value pointed at by a pointer
to a _Bool???)

If you assign the actual pointer isn't it always true except for a NULL
pointer (in case it would ALMOST always be false)?

I don't see what the "revelation" was here...

--
Mabden
Nov 15 '05 #43
On Fri, 21 Oct 2005 09:39:56 +0000, Mabden wrote:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
I was about to disagree. Fortunately, I looked it up first; you can
assign a pointer value directly to a _Bool. Interesting.
What does that mean? Assign the pointer to a _Bool or the value pointed at
to a _Bool? The former seems nonsensical,

It's consistent with pointer usage in conditional expressions.
the later seems obvious (why
_wouldn't_ you be able to assign the value pointed at by a pointer to a
_Bool???)
The assertion referred to the pointer's value, not the pointed-to value.
If you assign the actual pointer isn't it always true except for a NULL
pointer (in case it would ALMOST always be false)?

Which exception(s) did you have in mind?

[...]
--
http://members.dodo.com.au/~netocrat
Nov 15 '05 #44
"Mabden" <mabden@sbc_global.net> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
I was about to disagree. Fortunately, I looked it up first; you can
assign a pointer value directly to a _Bool. Interesting.
What does that mean? Assign the pointer to a _Bool or the value pointed
at to a _Bool? The former seems nonsensical, the later seems obvious
(why _wouldn't_ you be able to assign the value pointed at by a pointer
to a _Bool???)

I meant exactly what I said.
If you assign the actual pointer isn't it always true except for a NULL
pointer (in case it would ALMOST always be false)?

I don't see what the "revelation" was here...

C99 6.5.16.1, "Simple assignment":

One of the following shall hold:
[...]
the left operand has type _Bool and the right is a pointer.
[...]
In _simple assignment_ (=), the value of the right operand is
converted to the type of the assignment expression and replaces
the value stored in the object designated by the left operand.

C99 6.3.1.2, "Boolean type":

When any scalar value is converted to _Bool, the result is 0 if
the value compares equal to 0; otherwise, the result is 1.

(Pointer types are scalar types.)

The conversion of pointers to _Bool should probably also be mentioned
in 6.3.2.3.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #45
Keith Thompson <ks***@mib.org> writes:

[snip]

C99 6.5.16.1, "Simple assignment":

One of the following shall hold:
[...]
the left operand has type _Bool and the right is a pointer.
[...]
In _simple assignment_ (=), the value of the right operand is
converted to the type of the assignment expression and replaces
the value stored in the object designated by the left operand.

C99 6.3.1.2, "Boolean type":

When any scalar value is converted to _Bool, the result is 0 if
the value compares equal to 0; otherwise, the result is 1.

(Pointer types are scalar types.)

The conversion of pointers to _Bool should probably also be mentioned
in 6.3.2.3.

That would go against the (implicit?) rule that requirements
in the Standard are stated in only one place. Could be a
footnote, though.
Nov 15 '05 #46
"Netocrat" <ne******@dodo.com.au> wrote in message
news:pa****************************@dodo.com.au...
On Fri, 21 Oct 2005 09:39:56 +0000, Mabden wrote:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
I was about to disagree. Fortunately, I looked it up first; you can assign a pointer value directly to a _Bool. Interesting.
What does that mean? Assign the pointer to a _Bool or the value pointed at to a _Bool? The former seems nonsensical,

It's consistent with pointer usage in conditional expressions.

But why? What for? Every pointer except (sometimes) NULL will be true.
Am I missing something?
Feel free to not talk in one sentence questions.

the later seems obvious (why
_wouldn't_ you be able to assign the value pointed at by a pointer to a _Bool???)

The assertion referred to the pointer's value, not the pointed-to

value.

OK, then it is always true?
If you assign the actual pointer isn't it always true except for a NULL pointer (in case it would ALMOST always be false)?

Which exception(s) did you have in mind?

The case on some hardware where NULL is not a pointer to location zero.
Or a non-zero NULL pointer. I don't know how to say it right to not just
get back another stupid one liner about how I said it wrong. What I mean
is that all pointers have an address in them that is not zero and would
become a "true" value. The only exception might be the all-zero pointer,
which we've decided may be NULL, be may also not be NULL. If you expect
NULL to equate to "false" you will be right 99.99999% of the time,
except on hardware where it is not true. THe hardware, or other hardware
/ software may decide to use zero address for something else and your
code on that combo will expect a non-NULL pointer to always be "true",
but in that case it may not be true as the pointer is all zeroes and
equates to "false".

In a world where NULL is NOT guaranteed to be zeroes, and other pointers
MAY be all zeroes, assigning a pointer to a _Bool is a "random"
operation.

It seems to me. I'm sure I could find something Zen-like to sum this up
if I wasn't late for work.
We'll have to go with: "each state of mind not touching on things, each
step not positioned anywhere."

--
Mabden
Nov 15 '05 #47
"Mabden" <mabden@sbc_global.net> writes:
"Netocrat" <ne******@dodo.com.au> wrote in message
news:pa****************************@dodo.com.au...
On Fri, 21 Oct 2005 09:39:56 +0000, Mabden wrote:
> "Keith Thompson" <ks***@mib.org> wrote in message
> news:ln************@nuthaus.mib.org...
>> I was about to disagree. Fortunately, I looked it up first; you
>> can assign a pointer value directly to a _Bool. Interesting.
>
> What does that mean? Assign the pointer to a _Bool or the value
> pointed at to a _Bool? The former seems nonsensical,
It's consistent with pointer usage in conditional expressions.

But why? What for? Every pointer except (sometimes) NULL will be true.
Am I missing something?

Yes. You should read section 5 of the C FAQ, "Null Pointers".

I think I've explained the whole thing sufficiently in another
response in this thread, but I'll try again here.

If you assign a pointer value to an object of type _Bool, the result
will be 1 (true) if the pointer value is non-null, and will be 0
(false) if the pointer value is null. There is no "sometimes".
OK, then it is always true?

No; see above.
> If you assign the actual pointer isn't it always true except for
> a NULL pointer (in case it would ALMOST always be false)?

Which exception(s) did you have in mind?

The case on some hardware where NULL is not a pointer to location zero.
Or a non-zero NULL pointer. I don't know how to say it right to not just
get back another stupid one liner about how I said it wrong. What I mean
is that all pointers have an address in them that is not zero and would
become a "true" value. The only exception might be the all-zero pointer,
which we've decided may be NULL, be may also not be NULL. If you expect
NULL to equate to "false" you will be right 99.99999% of the time,
except on hardware where it is not true. THe hardware, or other hardware
/ software may decide to use zero address for something else and your
code on that combo will expect a non-NULL pointer to always be "true",
but in that case it may not be true as the pointer is all zeroes and
equates to "false".

In a world where NULL is NOT guaranteed to be zeroes, and other pointers
MAY be all zeroes, assigning a pointer to a _Bool is a "random"
operation.

It's a bit clearer to refer to a "null pointer" rather than a "NULL
pointer". The term "null pointer" is defined in the standard. "NULL"
is a macro that expands to a "null pointer constant" (which is
distinct from a "null pointer").

It doesn't matter whether a null pointer is represented as
all-bits-zero or as something else. The constant 0 in C program
source is a null pointer constant; if converted to a pointer type, the
result is a null pointer. The internal representation of a null
pointer is irrelevant, just as the representation of a floating-point
value 0.0 is irrelevant. Both are likely to be all-bits-zero, but
they aren't required to be.

Again, please read section 5 of the C FAQ. It doesn't discuss _Bool,
but it does explain null pointers very well.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #48
Mabden wrote:
"Netocrat" <ne******@dodo.com.au> wrote in message
news:pa****************************@dodo.com.au...
On Fri, 21 Oct 2005 09:39:56 +0000, Mabden wrote:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...

I was about to disagree. Fortunately, I looked it up first; you
can assign a pointer value directly to a _Bool. Interesting.

What does that mean? Assign the pointer to a _Bool or the value
pointed atto a _Bool? The former seems nonsensical,
It's consistent with pointer usage in conditional expressions.

But why? What for? Every pointer except (sometimes) NULL will be true.
Am I missing something?

Yes, you are missing that a null pointer *never* evaluates to true and a
null pointer *always* evaluates to true.
Feel free to not talk in one sentence questions.
the later seems obvious (why
_wouldn't_ you be able to assign the value pointed at by a pointer
to a _Bool???)
The assertion referred to the pointer's value, not the pointed-to
value.

OK, then it is always true?
If you assign the actual pointer isn't it always true except for a
NULL pointer (in case it would ALMOST always be false)?

Which exception(s) did you have in mind?

The case on some hardware where NULL is not a pointer to location zero.
Or a non-zero NULL pointer. I don't know how to say it right to not just

<snip>
In a world where NULL is NOT guaranteed to be zeroes, and other pointers
MAY be all zeroes, assigning a pointer to a _Bool is a "random"
operation.
The representation of pointers is *completely* irrelevant. If the bit
pattern of the null pointer is the same as the bit pattern of the int 1
it will *still* evaluate to false in a boolean context. If a non null
pointer happens to have a bit representation of all bits zero it will
*still* evaluate to true in a boolean context.

The best thing to do is completely forget that pointers even *have* bit
patterns, just treat them as opaque objects.
It seems to me. I'm sure I could find something Zen-like to sum this up
if I wasn't late for work.
We'll have to go with: "each state of mind not touching on things, each
step not positioned anywhere."

Zen is irrelevant to clear black and white problems of fact where there
is an absolute reference. Try reading a C text book such as K&R2 instead
of relying on philosophy and you might actually stand a chance.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #49
"Flash Gordon" <sp**@flash-gordon.me.uk> wrote in message
news:a9************@news.flash-gordon.me.uk...
Mabden wrote:
"Netocrat" <ne******@dodo.com.au> wrote in message
news:pa****************************@dodo.com.au...
On Fri, 21 Oct 2005 09:39:56 +0000, Mabden wrote:

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...

>I was about to disagree. Fortunately, I looked it up first; you
>can assign a pointer value directly to a _Bool. Interesting.

What does that mean? Assign the pointer to a _Bool or the value
pointed at
to a _Bool? The former seems nonsensical,

It's consistent with pointer usage in conditional expressions.

But why? What for? Every pointer except (sometimes) NULL will be true.
Am I missing something?

Yes, you are missing that a null pointer *never* evaluates to true and

a null pointer *always* evaluates to true.
Well, that helps clear it up. Let me write that down. never = always.
Got it.
The assertion referred to the pointer's value, not the pointed-to
value.

OK, then it is always true?
If you assign the actual pointer isn't it always true except for a
NULL pointer (in case it would ALMOST always be false)?

Which exception(s) did you have in mind?

The case on some hardware where NULL is not a pointer to location zero. Or a non-zero NULL pointer. I don't know how to say it right to not just
<snip>
In a world where NULL is NOT guaranteed to be zeroes, and other
pointers MAY be all zeroes, assigning a pointer to a _Bool is a "random"
operation.

The representation of pointers is *completely* irrelevant. If the bit
pattern of the null pointer is the same as the bit pattern of the int

1 it will *still* evaluate to false in a boolean context. If a non null
pointer happens to have a bit representation of all bits zero it will
*still* evaluate to true in a boolean context.

The best thing to do is completely forget that pointers even *have* bit patterns, just treat them as opaque objects.
OK, assume that I have. What do I do with a boolean value of a pointer?
What program needs this device? Why am I turning a things that points
into a thing that is TRUE or FALSE? Is North true? Is East false? Why is
this being done?

And why does it take 3 emails to get this question answered? Did I
stutter the first time???
It seems to me. I'm sure I could find something Zen-like to sum this up if I wasn't late for work.
We'll have to go with: "each state of mind not touching on things, each step not positioned anywhere."

Zen is irrelevant to clear black and white problems of fact where

there is an absolute reference. Try reading a C text book such as K&R2 instead of relying on philosophy and you might actually stand a chance.

Zen is never irrelevant; you merely chose to ignore wisdom, and eschew
thought.

Seriously, you don't think that quote describes pointers and NULL
pointers, even a little...? :-(
Are you taking into consideration that the words are from thousands of
years ago, and there may not have been as many computers in common usage
your post... You wanted something about an arrow, didn't you? I'll try
to find something about an arrow.

--
Mabden
Nov 15 '05 #50