The lack of a boolean data type in C

R

Random832

2006-12-20 said:
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.
 
R

Random832

2006-12-20 said:
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.
 
E

Eric Sosman

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.
[...]

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

CBFalconer

Random832 said:
CBFalconer wrote:
.... snip ...

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.
 
G

Guest

jaysome said:
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?

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.
 
C

CBFalconer

Thad said:
The header <iso646.h> was 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.
 
R

Random832

2006-12-20 said:
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.
 
T

Thad Smith

CBFalconer said:
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.h> was added in 1995, so there should probably be a separate
test for its inclusion.
 
D

Default User

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

jacob navia

Default User a écrit :
KimmoA wrote:




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
 
K

Keith Thompson

Random832 said:
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)?
 
K

Keith Thompson

jacob navia said:
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.
 
K

Keith Thompson

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

Keith Thompson

CBFalconer said:
#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.
 
S

Simon Biber

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

Eric Sosman

Keith said:
CBFalconer said:
#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!
 
R

Random832

2006-12-21 said:
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?)
 
C

CBFalconer

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

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,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top