By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,133 Members | 1,294 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,133 IT Pros & Developers. It's quick & easy.

The lack of a boolean data type in C

P: n/a
First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.

OK. Some of you might refer to C99 and its _Bool (what's up with the
uppercase 'B' anyway?) and the header you can include (apparently) to
get a real "bool". This isn't my point, however -- it should have been
there from the beginning.

char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree. Plus, it's
still too large.

"int some_bool = 0;" is what I -- and everyone else, I assume -- use
for bools. But an int is a very large data type for something that will
only ever be true or false (1 or 0). This really, really bugs me.

Why, back when C was designed, didn't they see a reason to build in a
boolean type into the language? Now it matters less, I guess, but back
then, there should have been very strong technical reasons. It just
doesn't make any sense whatsoever to me.

I have asked many people about this for quite some time, and they are
all just telling me that I'm silly for bringing it up. Why? It's not
that I NEED a bool to get anything done -- it's the principle. Saving
resources and coding a little more prettily is a Good Thing (TM) IMO.

So... can somebody properly explain this to me once and for all? I'm
sure there MUST be a logical explanation that nobody seems to really
understand. The madness must end.

bool some_bool = 0; /* How great it would be... */

Dec 19 '06 #1
Share this Question
Share on Google+
76 Replies


P: n/a
KimmoA wrote
(in article
<11*********************@i12g2000cwa.googlegroups. com>):
First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.
hasn't been a problem for, oh, 30 years?
OK. Some of you might refer to C99 and its _Bool (what's up with the
uppercase 'B' anyway?) and the header you can include (apparently) to
get a real "bool".
No, actually I don't prefer anything with leading _ chars in it.
This isn't my point, however -- it should have been
there from the beginning.
Not really needed.
char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree. Plus, it's
still too large.
Use a typedef to confuse yourself so you feel better. :-) As
for being to large, on what platform is it too large? Does
anyone really need hundreds of them floating around? If so,
pack them into bitfields.
"int some_bool = 0;" is what I -- and everyone else, I assume -- use
for bools. But an int is a very large data type for something that will
only ever be true or false (1 or 0). This really, really bugs me.
Then don't use int.
Why, back when C was designed, didn't they see a reason to build in a
boolean type into the language? Now it matters less, I guess, but back
then, there should have been very strong technical reasons. It just
doesn't make any sense whatsoever to me.
It wasn't needed, as decades of programmers demonstrated.
--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw

Dec 19 '06 #2

P: n/a
"KimmoA" <ki****@gmail.comwrites:
First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.

OK. Some of you might refer to C99 and its _Bool (what's up with the
uppercase 'B' anyway?) and the header you can include (apparently) to
get a real "bool". This isn't my point, however -- it should have been
there from the beginning.
Ok -- but it wasn't. We can't retroactively fix it.

As for the name "_Bool", it was chosen to avoid colliding with any
identifiers in existing user code. There's plenty of C90 code that
uses "bool" as an identifier, as in:
typedef enum { false, true } bool;
so making "bool" a keyword would have broken any such code.

An identifier starting with an underscore and an uppercase letter is
reserved, so the new standard was free to use it for its own purposes.

When C was first being designed, it was felt that having expressions
treated as false if their value is zero, and as true if their value is
non-zero, was good enough. (A lot of people still feel that way.)
char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree. Plus, it's
still too large.
char is the smallest possible object type other than a bit field.
Type _Bool has a size of at least one byte; it may even be bigger.

Suppose C had a built-in boolean type with a size of 1 bit. It would
be the only such type in the language (apart from bit fields). Taking
the address of such an object would create considerable problems. On
many systems, the code to extract the single relevant bit from the
byte or word containing such an object would far exceed the savings in
data size. Most likely the compiler would add padding anyway, so you
wouldn't save anything.
"int some_bool = 0;" is what I -- and everyone else, I assume -- use
for bools. But an int is a very large data type for something that will
only ever be true or false (1 or 0). This really, really bugs me.
I suggest getting over it. A single int isn't all that big. If the
size bothers you, use a char; it's equally capable of holding the
values 0 and 1. If you want to hold a large array of booleans, one
bit per element, there are ways to do it with bitwise operations (I
agree that a more direct approach to this would be nice, but there
hasn't been enough of a demand for it to justify adding it to the
language).

[snip]
So... can somebody properly explain this to me once and for all? I'm
sure there MUST be a logical explanation that nobody seems to really
understand. The madness must end.
The madness has ended, assuming you can find a compiler that
implements that portion of C99.
bool some_bool = 0; /* How great it would be... */
#include <stdbool.h>

bool some_bool = false; /* What was your problem, again? */

And if your implementation doesn't support _Bool or <stdbool.h>, you
can always define your own Boolean type; for example:

typedef enum { false, true } bool;

--
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.
Dec 19 '06 #3

P: n/a
KimmoA wrote:
First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.

OK. Some of you might refer to C99 and its _Bool (what's up with the
uppercase 'B' anyway?) and the header you can include (apparently) to
get a real "bool". This isn't my point, however -- it should have been
there from the beginning.

char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree. Plus, it's
still too large.
It doesn't feel wrong to me. Plus you can always write
typedef char bool ;
"int some_bool = 0;" is what I -- and everyone else, I assume -- use
for bools. But an int is a very large data type for something that will
only ever be true or false (1 or 0). This really, really bugs me.

Why, back when C was designed, didn't they see a reason to build in a
boolean type into the language? Now it matters less, I guess, but back
then, there should have been very strong technical reasons. It just
doesn't make any sense whatsoever to me.
I assume because the compiler needed to be small so there
was no reason to add a type which could be emulated very
easily with what the language already had available.
I have asked many people about this for quite some time, and they are
all just telling me that I'm silly for bringing it up. Why? It's not
that I NEED a bool to get anything done -- it's the principle. Saving
resources and coding a little more prettily is a Good Thing (TM) IMO.
You can code just fine without a bool. As for saving resources
what makes you think that you're saving any ? If your programme
uses just one bool then it will still be stored in one memory cell
or one register so you still get wasted bits. If you use several bools
in the same programme then the compiler could put them in the
same memory cell or register but then retrieving the value of each
one would be slower so you would save memory but lose speed.
So... can somebody properly explain this to me once and for all? I'm
sure there MUST be a logical explanation that nobody seems to really
understand. The madness must end.

bool some_bool = 0; /* How great it would be... */
Dec 19 '06 #4

P: n/a

"Keith Thompson" <ks***@mib.orgwrote in message
Suppose C had a built-in boolean type with a size of 1 bit. It would
be the only such type in the language (apart from bit fields). Taking
the address of such an object would create considerable problems. On
many systems, the code to extract the single relevant bit from the
byte or word containing such an object would far exceed the savings in
data size. Most likely the compiler would add padding anyway, so you
wouldn't save anything.
You could have extra bits to represent the bit offset, as 32-bit read/write
machines do with char pointers. 32 bit chars are a pain.
Or you could pad to one byte, which is the sensible way of doing it.
This would mean that
bool flag = 1;
flag += 1;

would set flag to zero.
It is handy to have a bool to document that a parameter or a return value is
a flag, and can only take two values. In retrospect, it would have been
better to have added a typedef in a standard header. As it is, bool breaks
libraries, because every incompetent goes and defines bool, Bool, Boolean or
BOOL_T and expects everyone who merely calls his functions to adopt his
convention, which of course you can't if you are calling someone else's
functions as well.

--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.

Dec 19 '06 #5

P: n/a
Keith Thompson wrote:
An identifier starting with an underscore and an uppercase letter is
reserved, so the new standard was free to use it for its own purposes.
Oh.
The madness has ended, assuming you can find a compiler that
implements that portion of C99.
It does, but... My point wasn't to get a workaround/fix, but to discuss
the reason behind this design choice. <:(

Spiros Bousbouras wrote:
char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree. Plus, it's
still too large.

It doesn't feel wrong to me. Plus you can always write
typedef char bool ;
It doesn't feel wrong for you to use a type called "char" for 0/1
values? :S
I assume because the compiler needed to be small so there
was no reason to add a type which could be emulated very
easily with what the language already had available.
Hmm... can anyone back this up?
You can code just fine without a bool. As for saving resources
what makes you think that you're saving any ? If your programme
uses just one bool then it will still be stored in one memory cell
or one register so you still get wasted bits. If you use several bools
in the same programme then the compiler could put them in the
same memory cell or register but then retrieving the value of each
one would be slower so you would save memory but lose speed.
Well... even if it's entirely pointless, being able to tell to the
compiler that a variable can only ever be "on" or "off" would feel so
much better. Nobody else seems to care, though... Hmpf.

Dec 19 '06 #6

P: n/a
KimmoA skrev:
First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.

char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree. Plus, it's
still too large.
As mentioned, If you need lots of booleans you can use bitfields.
Besides, int is typically the most efficient type when it comes to
execution speed.
Why, back when C was designed, didn't they see a reason to build in a
boolean type into the language?
Because it was (and is) not strictly needed and the designers wanted to
keep the language small.
I have asked many people about this for quite some time, and they are
all just telling me that I'm silly for bringing it up. Why? It's not
that I NEED a bool to get anything done -- it's the principle. Saving
resources and coding a little more prettily is a Good Thing (TM) IMO.
I agree that the use of a boolean type make declarations more
self-documenting than using int:s with boolean semantics.
So... can somebody properly explain this to me once and for all? I'm
sure there MUST be a logical explanation that nobody seems to really
understand. The madness must end.
I think we have.
bool some_bool = 0; /* How great it would be... */
Well, just include stdbool.h and you have it.
August
Dec 19 '06 #7

P: n/a
In article <zO*********************@bt.com>,
Malcolm <re*******@btinternet.comwrote:
>It is handy to have a bool to document that a parameter or a return value is
a flag, and can only take two values.
In the maple programming language, the boolean type can have any
of -three- values: true, false, and FAIL; FAIL is used when a
logic reselution is required but the matter cannot be decided -- such
as asking is(x 1) when x has not been given a specific value
(maple handles symbolic computations.)

My point (and I do have a point), is that there are often cases where
routines don't *really* fall neatly into two-valued logic: they
tend to fall more naturally into "true", "false", and "something's wrong".

--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers
Dec 19 '06 #8

P: n/a
KimmoA wrote:
>
.... snip ...
>
So... can somebody properly explain this to me once and for all?
I'm sure there MUST be a logical explanation that nobody seems to
really understand. The madness must end.

bool some_bool = 0; /* How great it would be... */
If you MUST have it, just #include "stdops.h", which follows:

/* stdops.h. Standard defines of operators, usable on C90 up */
#ifndef H_stdops_h
#define H_stdops_h
#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L)
/* The following from C99 - must define for C90 */
#include <stdbool.h /* define bool, true, false */
#include <iso646.h /* define not, and, or */
#else
#define false 0
#define true 1
typedef int bool;
#define not !
#define and &&
#define or ||
#define xor ^
#endif
#endif

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Dec 19 '06 #9

P: n/a

"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.cawrote in message
In article <zO*********************@bt.com>,
Malcolm <re*******@btinternet.comwrote:
>>It is handy to have a bool to document that a parameter or a return value
is
a flag, and can only take two values.

In the maple programming language, the boolean type can have any
of -three- values: true, false, and FAIL; FAIL is used when a
logic reselution is required but the matter cannot be decided -- such
as asking is(x 1) when x has not been given a specific value
(maple handles symbolic computations.)

My point (and I do have a point), is that there are often cases where
routines don't *really* fall neatly into two-valued logic: they
tend to fall more naturally into "true", "false", and "something's wrong".
That's a good point.
"Have you stopped beating your wife", for people, is an unproblematic yes/no
question. But for most of us, we'd want to say "that question makes an
untrue assumption".

However C doesn't do errors well. My own view is that exception handling
C++/ Java style isn't the answer either, though it is better than
hnad-coding error paths. I'm still looking for a good technique.

--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.

Dec 19 '06 #10

P: n/a
Walter Roberson wrote:
In article <zO*********************@bt.com>,
Malcolm <re*******@btinternet.comwrote:
It is handy to have a bool to document that a parameter or a return
value is a flag, and can only take two values.

In the maple programming language, the boolean type can have any
of -three- values: true, false, and FAIL; FAIL is used when a
logic reselution is required but the matter cannot be decided -- such
as asking is(x 1) when x has not been given a specific value
(maple handles symbolic computations.)

My point (and I do have a point), is that there are often cases where
routines don't really fall neatly into two-valued logic: they
tend to fall more naturally into "true", "false", and "something's
wrong".
Now you listen here mister, two-valued logic built this great
civilization. You just get on out of here with the multi-valued logic.
We'll be having no truck with that.


Brian
Dec 19 '06 #11

P: n/a
2006-12-19 <45***************@yahoo.com>,
CBFalconer wrote:
KimmoA wrote:
>>
... snip ...
>>
So... can somebody properly explain this to me once and for all?
I'm sure there MUST be a logical explanation that nobody seems to
really understand. The madness must end.

bool some_bool = 0; /* How great it would be... */

If you MUST have it, just #include "stdops.h", which follows:
typedef int bool;
Quick, what is (bool)0x10000L? What's ((bool)1)^((bool)2)?
Dec 20 '06 #12

P: n/a
Random832 wrote:
2006-12-19 <45***************@yahoo.com>,
CBFalconer wrote:
>KimmoA wrote:
... snip ...
>>So... can somebody properly explain this to me once and for all?
I'm sure there MUST be a logical explanation that nobody seems to
really understand. The madness must end.

bool some_bool = 0; /* How great it would be... */
If you MUST have it, just #include "stdops.h", which follows:
typedef int bool;

Quick, what is (bool)0x10000L? What's ((bool)1)^((bool)2)?
If C99's _Bool is in use, they are 1 and 0 respectively. Anything
non-zero becomes 1 when converted to _Bool. (1^1) is 0.

If bool is just a typedef for int, then (bool)0x10000L may have the
value 0x10000 (if int is large enough) or "either the result is
implementation-defined or an implementation-defined signal is raised".
The second expression will have value 3 since (1^2) is 3.

--
Simon.
Dec 20 '06 #13

P: n/a
On 19 Dec 2006 13:48:42 -0800, "KimmoA" <ki****@gmail.comwrote:
>First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.

OK. Some of you might refer to C99 and its _Bool (what's up with the
uppercase 'B' anyway?) and the header you can include (apparently) to
get a real "bool". This isn't my point, however -- it should have been
there from the beginning.

char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree. Plus, it's
still too large.

"int some_bool = 0;" is what I -- and everyone else, I assume -- use
for bools. But an int is a very large data type for something that will
only ever be true or false (1 or 0). This really, really bugs me.

Why, back when C was designed, didn't they see a reason to build in a
boolean type into the language? Now it matters less, I guess, but back
then, there should have been very strong technical reasons. It just
doesn't make any sense whatsoever to me.

I have asked many people about this for quite some time, and they are
all just telling me that I'm silly for bringing it up. Why? It's not
that I NEED a bool to get anything done -- it's the principle. Saving
resources and coding a little more prettily is a Good Thing (TM) IMO.

So... can somebody properly explain this to me once and for all? I'm
sure there MUST be a logical explanation that nobody seems to really
understand. The madness must end.

bool some_bool = 0; /* How great it would be... */
I agree with your point.

It would have been nice if something like "bool" was a built-in type,
along with the "true" and "false" keywords.

My "workaround" has always been:

typedef unsigned char boolean;
#define FALSE 0
#define TRUE 1

This allows you to use these types of statments:

boolean oven_is_on;
oven_is_on = FALSE;
oven_is_on = TRUE;
if ( oven_is_on )
if ( !oven_is_on )
char *OVEN_STRINGS[2] = {"OFF", "ON"};
printf("Oven is %s\n", OVEN_STRINGS[oven_is_on]);

It's definitely not perfect. Someone could readily do this, which is
undefined behavior:

oven_is_on = 2;
printf("Oven is %s\n", OVEN_STRINGS[oven_is_on]);

That type of error should be caught statically (meaning by the
compiler, or your favorite static code analyzer). Of course it's not
difficult to defeat even this course of defense:

static void print_state(boolean oven_is_on)
{
printf("Oven is %s\n", OVEN_STRINGS[oven_is_on]);
}

boolean oven_is_on = 2;
print_state(oven_is_on);

--
jay
Dec 20 '06 #14

P: n/a
Simon Biber wrote:
Random832 wrote:
>CBFalconer wrote:
>>KimmoA wrote:
... snip ...
So... can somebody properly explain this to me once and for all?
I'm sure there MUST be a logical explanation that nobody seems to
really understand. The madness must end.

bool some_bool = 0; /* How great it would be... */
If you MUST have it, just #include "stdops.h", which follows:
typedef int bool;
Here Random832 has unwisely snipped most of stdops.h, which adapts
itself to the standard in force and defines true and false. Thus
he loses the point of having that header. He also failed to mark
the snippage.
>Quick, what is (bool)0x10000L? What's ((bool)1)^((bool)2)?

If C99's _Bool is in use, they are 1 and 0 respectively. Anything
non-zero becomes 1 when converted to _Bool. (1^1) is 0.

If bool is just a typedef for int, then (bool)0x10000L may have the
value 0x10000 (if int is large enough) or "either the result is
implementation-defined or an implementation-defined signal is raised".
The second expression will have value 3 since (1^2) is 3.
You can always:

#define itobool(i) (!!(i))

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 20 '06 #15

P: n/a
jaysome said:
On 19 Dec 2006 13:48:42 -0800, "KimmoA" <ki****@gmail.comwrote:
>>First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.

OK. Some of you might refer to C99 and its _Bool (what's up with the
uppercase 'B' anyway?) and the header you can include (apparently) to
get a real "bool". This isn't my point, however -- it should have been
there from the beginning.

char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree. Plus, it's
still too large.

"int some_bool = 0;" is what I -- and everyone else, I assume -- use
for bools. But an int is a very large data type for something that will
only ever be true or false (1 or 0). This really, really bugs me.

Why, back when C was designed, didn't they see a reason to build in a
boolean type into the language? Now it matters less, I guess, but back
then, there should have been very strong technical reasons. It just
doesn't make any sense whatsoever to me.

I have asked many people about this for quite some time, and they are
all just telling me that I'm silly for bringing it up. Why? It's not
that I NEED a bool to get anything done -- it's the principle. Saving
resources and coding a little more prettily is a Good Thing (TM) IMO.

So... can somebody properly explain this to me once and for all? I'm
sure there MUST be a logical explanation that nobody seems to really
understand. The madness must end.

bool some_bool = 0; /* How great it would be... */

I agree with your point.

It would have been nice if something like "bool" was a built-in type,
along with the "true" and "false" keywords.

My "workaround" has always been:

typedef unsigned char boolean;
#define FALSE 0
#define TRUE 1

This allows you to use these types of statments:

boolean oven_is_on;
oven_is_on = FALSE;
oven_is_on = TRUE;
if ( oven_is_on )
if ( !oven_is_on )
char *OVEN_STRINGS[2] = {"OFF", "ON"};
printf("Oven is %s\n", OVEN_STRINGS[oven_is_on]);
But your OVEN_STRINGS argument to printf is not defined.

It might look as if it is, but it isn't.

To guard against this kind of error, *always* use a compound statement as
the body of an if/else/for/while/do-while. In this case, the error isn't
too serious because it'll lead to a compilation diagnostic message, but
that isn't /always/ the case by any means.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 20 '06 #16

P: n/a
Richard Heathfield wrote:
jaysome said:
My "workaround" has always been:

typedef unsigned char boolean;
#define FALSE 0
#define TRUE 1

This allows you to use these types of statments:

boolean oven_is_on;
oven_is_on = FALSE;
oven_is_on = TRUE;
if ( oven_is_on )
if ( !oven_is_on )
char *OVEN_STRINGS[2] = {"OFF", "ON"};
printf("Oven is %s\n", OVEN_STRINGS[oven_is_on]);

But your OVEN_STRINGS argument to printf is not defined.
The code is probably intended as a series of fragments, but ignoring
that, since you did too:

Firstly, there is no argument to printf. There is a syntax error.
Anything after a syntax error cannot be given a meaning. Secondly, if
the code were syntactically valid with a meaning consistent with the
rest of C, OVEN_STRINGS would be defined in C90, since C90 has no
implicit block for selection statements.
It might look as if it is, but it isn't.

To guard against this kind of error, *always* use a compound statement as
the body of an if/else/for/while/do-while. In this case, the error isn't
too serious because it'll lead to a compilation diagnostic message, but
that isn't /always/ the case by any means.
If you use a compound statement, you introduce a block, and anything
declared in it goes out of scope afterwards. If you don't use a
compound statement, and there is no implicit block, nothing goes out of
scope. This is invalid C99, but valid C90:

int main(void) {
if(0)
(enum { zero }) 0;
return zero;
}

(Yes, it's horrible style in this case, and perhaps all cases.)

Dec 20 '06 #17

P: n/a
On 20 Dec 2006 00:51:49 -0800, "Harald van D?k" <tr*****@gmail.com>
wrote:
>Richard Heathfield wrote:
>jaysome said:
My "workaround" has always been:

typedef unsigned char boolean;
#define FALSE 0
#define TRUE 1

This allows you to use these types of statments:

boolean oven_is_on;
oven_is_on = FALSE;
oven_is_on = TRUE;
if ( oven_is_on )
if ( !oven_is_on )
char *OVEN_STRINGS[2] = {"OFF", "ON"};
printf("Oven is %s\n", OVEN_STRINGS[oven_is_on]);

But your OVEN_STRINGS argument to printf is not defined.

The code is probably intended as a series of fragments, but ignoring
that, since you did too:
Yes, fragments.
>Firstly, there is no argument to printf. There is a syntax error.
Huh?

The prototype for printf() is:

int printf(const char *format, ...);

How is the above a syntax error?

--
jay
Dec 20 '06 #18

P: n/a
KimmoA a écrit :
First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.

OK. Some of you might refer to C99 and its _Bool (what's up with the
uppercase 'B' anyway?) and the header you can include (apparently) to
get a real "bool". This isn't my point, however -- it should have been
there from the beginning.

char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree. Plus, it's
still too large.

"int some_bool = 0;" is what I -- and everyone else, I assume -- use
for bools. But an int is a very large data type for something that will
only ever be true or false (1 or 0). This really, really bugs me.

Why, back when C was designed, didn't they see a reason to build in a
boolean type into the language? Now it matters less, I guess, but back
then, there should have been very strong technical reasons. It just
doesn't make any sense whatsoever to me.

I have asked many people about this for quite some time, and they are
all just telling me that I'm silly for bringing it up. Why? It's not
that I NEED a bool to get anything done -- it's the principle. Saving
resources and coding a little more prettily is a Good Thing (TM) IMO.

So... can somebody properly explain this to me once and for all? I'm
sure there MUST be a logical explanation that nobody seems to really
understand. The madness must end.

bool some_bool = 0; /* How great it would be... */
There is one point where you are right is in the lack
of boolean arrays.

If I declare

bool tab[8];

it would be sensible to expect that those eight bits would be
stored in 1 byte (if byte is 8 bits).

It is always stated that then

bool *p = &tab[3];

would have no meaning but it would be easy to say that for boolean
pointers, they either

1) Point to the byte where the bit is stored and not to the bit itself.
2) Have some different structure with two pointers: one for the byte and
another for the bit.

Option (2) would be really difficult to implement, having two kinds of
pointers would make things very difficult everywhere.
Option (1) would be simple: pointers do not work with those arrays,
and only array notation would be allowed.

Obviously it is possible to construct a macrology for all this, using
bit masks. That is a solution outside the language though.

jacob
Dec 20 '06 #19

P: n/a
"KimmoA" <ki****@gmail.comwrote:
First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.
I would class that as one of the least important flaws in the language.
char is a small int. We all know that. However, "char some_bool = 0;"
simply feels wrong, and I think that most of you agree.
I don't know about most of us, but I disagree. (Although I'd use
unsigned char by preference.)
Plus, it's still too large.
Too large? How many of these do you want? Thousands?
"int some_bool = 0;" is what I -- and everyone else, I assume -- use
for bools. But an int is a very large data type for something that will
only ever be true or false (1 or 0). This really, really bugs me.
I can only suggest that you find something more serious to let yourself
be bugged by.
The madness must end.
Well, quite.

Richard
Dec 20 '06 #20

P: n/a
Richard Bos wrote:
Too large? How many of these do you want? Thousands?
It's the principle.
I can only suggest that you find something more serious to let yourself
be bugged by.
Sorry for caring about stuff, I guess...

Dec 20 '06 #21

P: n/a
2006-12-20 <45**********@news.peopletelecom.com.au>,
Simon Biber wrote:
Random832 wrote:
>2006-12-19 <45***************@yahoo.com>,
CBFalconer wrote:
>>KimmoA wrote:
... snip ...
So... can somebody properly explain this to me once and for all?
I'm sure there MUST be a logical explanation that nobody seems to
really understand. The madness must end.

bool some_bool = 0; /* How great it would be... */
If you MUST have it, just #include "stdops.h", which follows:
typedef int bool;

Quick, what is (bool)0x10000L? What's ((bool)1)^((bool)2)?

If C99's _Bool is in use, they are 1 and 0 respectively. Anything
non-zero becomes 1 when converted to _Bool. (1^1) is 0.

If bool is just a typedef for int, then (bool)0x10000L may have the
value 0x10000 (if int is large enough) or "either the result is
implementation-defined or an implementation-defined signal is raised".
The second expression will have value 3 since (1^2) is 3.
Right. My point was, a typedef for int is not a substitute for a real
boolean type.
Dec 20 '06 #22

P: n/a
2006-12-20 <45***************@yahoo.com>,
CBFalconer wrote:
Simon Biber wrote:
>Random832 wrote:
>>CBFalconer wrote:
KimmoA wrote:
... snip ...
So... can somebody properly explain this to me once and for all?
I'm sure there MUST be a logical explanation that nobody seems to
really understand. The madness must end.
>
bool some_bool = 0; /* How great it would be... */
If you MUST have it, just #include "stdops.h", which follows:
typedef int bool;

Here Random832 has unwisely snipped most of stdops.h, which adapts
itself to the standard in force
I'm not sure what "adapts itself to the standard in force" means.
and defines true and false. Thus
he loses the point of having that header. He also failed to mark
the snippage.
I kept the part relevant to my point.
Dec 20 '06 #23

P: n/a
CBFalconer wrote:
If you MUST have it, just #include "stdops.h", which follows:

/* stdops.h. Standard defines of operators, usable on C90 up */
#ifndef H_stdops_h
#define H_stdops_h
#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L)
/* The following from C99 - must define for C90 */
#include <stdbool.h /* define bool, true, false */
#include <iso646.h /* define not, and, or */
#else
#define false 0
#define true 1
typedef int bool;
#define not !
#define and &&
#define or ||
#define xor ^
#endif
The header <iso646.hwas added in 1995, so there should probably be a separate
test for its inclusion.

--
Thad
Dec 20 '06 #24

P: n/a
KimmoA wrote:
First of all: I love C and think that it's beautiful. However, there is
at least one MAJOR flaw: the lack of a boolean type.
[...]
Right. And that MAJOR flaw is why C never caught on.

('sfunny. In a discussion forum devoted to another language,
some people have posited that the *presence* of a Boolean type is
a flaw! Seems like there's just no way to please everyone: either
the Republicrats or the Democans will take issue with anything you
try to do.)

--
Eric Sosman
es*****@acm-dot-org.invalid
Dec 20 '06 #25

P: n/a
jaysome wrote:
On 20 Dec 2006 00:51:49 -0800, "Harald van D?k" <tr*****@gmail.com>
wrote:
Richard Heathfield wrote:
jaysome said:
My "workaround" has always been:

typedef unsigned char boolean;
#define FALSE 0
#define TRUE 1

This allows you to use these types of statments:

boolean oven_is_on;
oven_is_on = FALSE;
oven_is_on = TRUE;
if ( oven_is_on )
if ( !oven_is_on )
char *OVEN_STRINGS[2] = {"OFF", "ON"};
printf("Oven is %s\n", OVEN_STRINGS[oven_is_on]);

But your OVEN_STRINGS argument to printf is not defined.
The code is probably intended as a series of fragments, but ignoring
that, since you did too:

Yes, fragments.
Firstly, there is no argument to printf. There is a syntax error.

Huh?
Richard Heathfield treated your code as one complete fragment, and in
reply so did I. As a single fragment, a statement is required on line
6, but a declaration is not a statement.

Dec 20 '06 #26

P: n/a
Random832 wrote:
CBFalconer wrote:
.... snip ...
>>
Here Random832 has unwisely snipped most of stdops.h, which adapts
itself to the standard in force

I'm not sure what "adapts itself to the standard in force" means.
It means it will operate correctly under either C99 or an earlier
version of the standard.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 20 '06 #27

P: n/a
Thad Smith wrote:
CBFalconer wrote:
>If you MUST have it, just #include "stdops.h", which follows:

/* stdops.h. Standard defines of operators, usable on C90 up */
#ifndef H_stdops_h
#define H_stdops_h
#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L)
/* The following from C99 - must define for C90 */
#include <stdbool.h /* define bool, true, false */
#include <iso646.h /* define not, and, or */
#else
#define false 0
#define true 1
typedef int bool;
#define not !
#define and &&
#define or ||
#define xor ^
#endif

The header <iso646.hwas added in 1995, so there should probably
be a separate test for its inclusion.
It won't be included unless C99 up is in force. I think that is
adequate.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 20 '06 #28

P: n/a
2006-12-20 <45***************@yahoo.com>,
CBFalconer wrote:
It means it will operate correctly under either C99 or an earlier
version of the standard.
I didn't even see that... *reads again* gah, that's a terrible idea.
Since _Bool behaves differently from int in several important ways, it'd
be better to have it define it as int consistently so it will behave the
same no matter which version of the standard you're using.

It'd be better to have ((bool)1)^((bool)2) always be 3 then to have it
be 0 under c99 and 3 on c89.
Dec 20 '06 #29

P: n/a
KimmoA wrote:
Richard Bos wrote:
Too large? How many of these do you want? Thousands?

It's the principle.
It's a silly one though. Even languages with built-in boolean types are
likely to have it be some machine-adressable type. You aren't
guaranteed to have it smaller than a char, and if fact seldom will.


Brian
Dec 20 '06 #30

P: n/a
Default User a écrit :
KimmoA wrote:

>>Richard Bos wrote:
>>>Too large? How many of these do you want? Thousands?

It's the principle.


It's a silly one though. Even languages with built-in boolean types are
likely to have it be some machine-adressable type. You aren't
guaranteed to have it smaller than a char, and if fact seldom will.


Brian
Boolean arrays in the APL language take only 1 bit per boolean
Dec 20 '06 #31

P: n/a
2006-12-20 <45***********************@news.orange.fr>,
jacob navia wrote:
Boolean arrays in the APL language take only 1 bit per boolean
Which is just one of, i'm sure, many reasons that C is not APL.
Dec 20 '06 #32

P: n/a
Random832 <ra****@random.yi.orgwrites:
2006-12-20 <45***************@yahoo.com>,
CBFalconer wrote:
>It means it will operate correctly under either C99 or an earlier
version of the standard.

I didn't even see that... *reads again* gah, that's a terrible idea.
Since _Bool behaves differently from int in several important ways, it'd
be better to have it define it as int consistently so it will behave the
same no matter which version of the standard you're using.
_Bool's behavior differ from int in *no* important ways if you use it
carefully. (Using it carefully is admittedly non-trivial.)
It'd be better to have ((bool)1)^((bool)2) always be 3 then to have it
be 0 under c99 and 3 on c89.
Why would anyone want to write ((bool)1)^((bool)2)?

--
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.
Dec 20 '06 #33

P: n/a
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
There is one point where you are right is in the lack
of boolean arrays.

If I declare

bool tab[8];

it would be sensible to expect that those eight bits would be
stored in 1 byte (if byte is 8 bits).
It would also be sensible to expect that each of those 8 objects would
occupy at least one byte, just like any other non-bit-field object.

But yes, it might be nice to have a syntax for bit arrays in C.
Ordinary array notation, though, already has a well-defined meaning
that's incompatible with bit arrays.
It is always stated that then

bool *p = &tab[3];

would have no meaning but it would be easy to say that for boolean
pointers, they either

1) Point to the byte where the bit is stored and not to the bit itself.
2) Have some different structure with two pointers: one for the byte and
another for the bit.

Option (2) would be really difficult to implement, having two kinds of
pointers would make things very difficult everywhere.
Yes, but there are real-world C implementations that already have two
or more kinds of pointers, sometimes of different sizes. Implementing
pointers to single bits would be no more difficult than, say, byte
pointers on a Cray vector system.
Option (1) would be simple: pointers do not work with those arrays,
and only array notation would be allowed.
You're suggesting that the elements of the array would be treated like
bit fields. In that case, &tab[3] should be illegal. Making it the
address of the byte containing tab[3], rather than of tab[3] itself,
doesn't make any sense.

--
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.
Dec 20 '06 #34

P: n/a
"KimmoA" <ki****@gmail.comwrites:
Richard Bos wrote:
>Too large? How many of these do you want? Thousands?

It's the principle.
What principle?

Seriously, can you state this principle of yours in general and yet
precise terms?

If your principle were, for example, "The language should let me do
anything I want to", then that's a fine principle, but I'm afraid
you're not going to get the language designers and implementers to go
along with it, at least not if you don't narrow it down a bit.
>I can only suggest that you find something more serious to let yourself
be bugged by.

Sorry for caring about stuff, I guess...
Caring about stuff is fine. The fact is, there are good reasons for
the language being the way it is. (There are also some bad reasons
for the language being the way it is.)

You want C to have had a built-in Boolean type from the beginning.
It didn't. I'm afrid there's really nothing we can do about that
beyond offering a very limited amount of sympathy.

There are other languages that *have* had a Boolean type from their
beginnings.

--
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.
Dec 20 '06 #35

P: n/a
CBFalconer <cb********@yahoo.comwrites:
[...]
#define false 0
#define true 1
typedef int bool;
[...]

Rather than the above, have you considered:

typedef enum { false, true } bool;

? It's very nearly equivalent, but I find it a bit better
esthetically.

--
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.
Dec 20 '06 #36

P: n/a
Keith Thompson wrote:
Random832 <ra****@random.yi.orgwrites:
>It'd be better to have ((bool)1)^((bool)2) always be 3 then to have it
be 0 under c99 and 3 on c89.

Why would anyone want to write ((bool)1)^((bool)2)?
Because C doesn't have a logical XOR operator.

If you want to perform a logical XOR, you can convert your values to
their Boolean equivalent (0 or 1) and then use the bitwise XOR.

Under C89 the correct way would be (!!a)^(!!b).

Under C99 you can do ((bool)a)^((bool)b) but this breaks when bool is
defined as int rather than _Bool.

--
Simon.
Dec 21 '06 #37

P: n/a
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
[...]
> #define false 0
#define true 1
typedef int bool;
[...]

Rather than the above, have you considered:

typedef enum { false, true } bool;

? It's very nearly equivalent, but I find it a bit better
esthetically.
"Aesthetically."

I once ran across this gem:

typedef enum { TRUE, FALSE } bool;

No foolin', I really did!

--
Eric Sosman
es*****@acm-dot-org.invalid
Dec 21 '06 #38

P: n/a
2006-12-21 <45**********@news.peopletelecom.com.au>,
Simon Biber wrote:
Keith Thompson wrote:
>Random832 <ra****@random.yi.orgwrites:
>>It'd be better to have ((bool)1)^((bool)2) always be 3 then to have it
be 0 under c99 and 3 on c89.

Why would anyone want to write ((bool)1)^((bool)2)?

Because C doesn't have a logical XOR operator.

If you want to perform a logical XOR, you can convert your values to
their Boolean equivalent (0 or 1) and then use the bitwise XOR.

Under C89 the correct way would be (!!a)^(!!b).

Under C99 you can do ((bool)a)^((bool)b) but this breaks when bool is
defined as int rather than _Bool.
Note that I did not intend that you'd actually do anything with the xor
operator and two casts to bool. That was just to simplify it to
a single-line example.

But if you're actually _storing_ bool's, it's nice to be able to
guarantee that they're 0 and 1 - and that you can convert a pointer
directly to a bool (null is 0, non-null is 1, right?)
Dec 21 '06 #39

P: n/a
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
[...]
> #define false 0
#define true 1
typedef int bool;
[...]

Rather than the above, have you considered:

typedef enum { false, true } bool;

? It's very nearly equivalent, but I find it a bit better
esthetically.
The C99 stdbool.h is intended to standardize these things. Thus I
wrote stdops.h to emulate the specifications in that standard as
closely as possible.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 21 '06 #40

P: n/a
On Tue, 19 Dec 2006 22:30:44 -0000, "Malcolm"
<re*******@btinternet.comwrote:
>
"Keith Thompson" <ks***@mib.orgwrote in message
>Suppose C had a built-in boolean type with a size of 1 bit. It would
be the only such type in the language (apart from bit fields). Taking
the address of such an object would create considerable problems. On
many systems, the code to extract the single relevant bit from the
byte or word containing such an object would far exceed the savings in
data size. Most likely the compiler would add padding anyway, so you
wouldn't save anything.
You could have extra bits to represent the bit offset, as 32-bit read/write
machines do with char pointers. 32 bit chars are a pain.
Or you could pad to one byte, which is the sensible way of doing it.
This would mean that
bool flag = 1;
flag += 1;

would set flag to zero.
Pretty sure in C99

bool flag=1;
flag++;

flag is now (still) == 1

Jim
Dec 21 '06 #41

P: n/a
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
[...]
> #define false 0
#define true 1
typedef int bool;

[...]

Rather than the above, have you considered:

typedef enum { false, true } bool;

? It's very nearly equivalent, but I find it a bit better
esthetically.
My preference as well. It would have been even better if C enums were
type safe.

--
Ian Collins.
Dec 21 '06 #42

P: n/a
Default User wrote:
KimmoA wrote:

>>Richard Bos wrote:
>>>Too large? How many of these do you want? Thousands?

It's the principle.


It's a silly one though. Even languages with built-in boolean types are
likely to have it be some machine-adressable type. You aren't
guaranteed to have it smaller than a char, and if fact seldom will.
Given a bool type, you can specialise or optimise operations or
constructs for that specific type, which you can't do with a user
defined equivalent.

<OTthis trick is used in the C++ standard library</OT>.

--
Ian Collins.
Dec 21 '06 #43

P: n/a
Keith Thompson wrote:
It's the principle.

What principle?
That it makes sense to have a boolean type? I still want to know what
you all use instead...
You want C to have had a built-in Boolean type from the beginning.
It didn't. I'm afrid there's really nothing we can do about that
beyond offering a very limited amount of sympathy.
Obviously I realize that nothing can be done about it now, but I want
to fully understand why they decided to design the language this way.
So far, nobody has really told me anything that truly convinces me that
it made sense.
There are other languages that *have* had a Boolean type from their
beginnings.
I know what you mean by this. You want me to switch to a different
language for questioning one single thing. That's silly, and there is
no other language that I'm even remotely interested in. I switched FROM
C++ to C, but at least C++ had the bool...

Dec 21 '06 #44

P: n/a
KimmoA said:
Keith Thompson wrote:
It's the principle.

What principle?

That it makes sense to have a boolean type? I still want to know what
you all use instead...
If I need one, I use an int. Who cares about the storage cost of one lousy
int? And if I need loads, I use an array of unsigned char and some bit
macros. One bit per bool.

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 21 '06 #45

P: n/a
>>>>"KA" == KimmoA <ki****@gmail.comwrites:

KAThat it makes sense to have a boolean type? I still want to
KAknow what you all use instead...

Integers.

KAObviously I realize that nothing can be done about it now, but
KAI want to fully understand why they decided to design the
KAlanguage this way. So far, nobody has really told me anything
KAthat truly convinces me that it made sense.

Because the only advantage is theoretical.

Imagine that you have a bool type. It's either an int or char with
syntactic sugar imposing constraints on its behavior, or it's a single
bit which needs to be extracted. The former gives you no real
advantage over what the language offers now, plus a whole lot of
potential for confusion, and the latter is likely to trade off speed
for theoretical purity.

Because it can't be predictably translated into machine code.

Microprocessors understand integers and floating-point numbers at a
very low level, but most often implement boolean as equal to zero or
not equal to zero. The C approach to Boolean math -- that zero is
false and non-zero is true -- maps directly to this approach. Adding
the conceit of Boolean variables to the language would either map
directly to this, giving the programmer no real advantage over using
integral types in the first place, or map to the extracting-bits approach.

In short: the benefit you get from a pure Boolean type is nonexistent.
That's why it's not in C. You have yet to show any compelling reason
to include it.

Charlton


--
Charlton Wilbur
cw*****@chromatico.net
Dec 21 '06 #46

P: n/a
Ian Collins wrote:
Default User wrote:
KimmoA wrote:

Richard Bos wrote:
>
Too large? How many of these do you want? Thousands?
>
It's the principle.

It's a silly one though. Even languages with built-in boolean types
are likely to have it be some machine-adressable type. You aren't
guaranteed to have it smaller than a char, and if fact seldom will.
Given a bool type, you can specialise or optimise operations or
constructs for that specific type, which you can't do with a user
defined equivalent.
True, but not what the OP was belly-aching about. He thinks a defined
type would save storage (char is still too big in his estimation), and
that's unlikely.

Brian
Dec 21 '06 #47

P: n/a
Richard Heathfield wrote:
KimmoA said:
Keith Thompson wrote:
It's the principle.
>
What principle?
That it makes sense to have a boolean type? I still want to know
what you all use instead...

If I need one, I use an int. Who cares about the storage cost of one
lousy int? And if I need loads, I use an array of unsigned char and
some bit macros. One bit per bool.
I did the latter for my text-adventure game. Mostly it was for the
feature that suppresses showing the room's long description if you've
been in it before. So I had a bit array that could be indexed by the
room number.

Like many features, I did it that way because the game was a training
tool while I was learning C and that seemed a good way to learn to do
bit arrays. Were I doing it from the beginning, I'd probably keep that
information in the room structure.


Brian
Dec 21 '06 #48

P: n/a
Default User wrote:
Ian Collins wrote:

>>Default User wrote:
>>>KimmoA wrote:

Richard Bos wrote:
>Too large? How many of these do you want? Thousands?

It's the principle.
It's a silly one though. Even languages with built-in boolean types
are likely to have it be some machine-adressable type. You aren't
guaranteed to have it smaller than a char, and if fact seldom will.

Given a bool type, you can specialise or optimise operations or
constructs for that specific type, which you can't do with a user
defined equivalent.

True, but not what the OP was belly-aching about. He thinks a defined
type would save storage (char is still too big in his estimation), and
that's unlikely.
I was thinking of the way C++ specialises vector<boolas a compact
vector of bits, which does save on storage. C could do this for arrays
of _Bool, but it would break too many addressing rules to be viable.

--
Ian Collins.
Dec 21 '06 #49

P: n/a
Richard Heathfield a écrit :
KimmoA said:

>>Keith Thompson wrote:
>>>>It's the principle.

What principle?

That it makes sense to have a boolean type? I still want to know what
you all use instead...


If I need one, I use an int. Who cares about the storage cost of one lousy
int? And if I need loads, I use an array of unsigned char and some bit
macros. One bit per bool.

<snip>
There are many processors with specialized bit shifting or
bit extracting instructions. The "macro" approach hides the
intention of the programmer behind a lot of shifts and
masks AND operations, making it impossible for the compiler
to do any optimizations specifically designed for bit arrays.
Dec 21 '06 #50

76 Replies

This discussion thread is closed

Replies have been disabled for this discussion.