The lack of a boolean data type in C

K

KimmoA

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... */
 
R

Randy Howard

KimmoA wrote
(in article
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.
 
K

Keith Thompson

KimmoA said:
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;
 
S

Spiros Bousbouras

KimmoA said:
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.
 
M

Malcolm

Keith Thompson said:
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.
 
K

KimmoA

Keith said:
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 said:
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.
 
A

August Karlstrom

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
 
C

CBFalconer

KimmoA said:
.... 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
 
W

Walter Roberson

Malcolm said:
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".
 
M

Malcolm

Walter Roberson said:
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.
 
D

Default User

Walter said:
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
 
S

Simon Biber

Random832 said:
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.
 
C

CBFalconer

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.
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))
 
J

jaysome

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);
 
R

Richard Heathfield

jaysome said:
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.
 
G

Guest

Richard said:
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.)
 
J

jaysome

Richard said:
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?
 
J

jacob navia

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
 
R

Richard Bos

KimmoA said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top