Boolean data type?

M

Martin Wells

I come from C++, and there's a type called "bool" in C++. It works
exactly like any other integer type except that when promoted, it
either becomes a one or a zero, so you can you bitwise operators as if
they were logical operators:

bool a = 5, b = 6;

if (a == b) DoSomething; /* This will execute */

What type is commonly used in C for playing around with boolean
values?

I'm writing code for an embedded systems project so I'll *really* have
to watch how much memory I'm using... so would it be wise to be
returning "int" from functions that I would otherwise (in C++) return
a bool from? For example

int QueryBit(char unsigned const *const pc, unsigned const index)
{
return *pc & (1U << index);
}

(Let's leave alone for the moment the issue of whether this should
instead be a macro)

I suppose I'm asking two questions:

a) What type is commonly used for booleans?
b) What type is commonly used for booleans when you've to go easy
on memory consumption?

Martin
 
P

pete

Martin said:
I come from C++, and there's a type called "bool" in C++. It works
exactly like any other integer type except that when promoted, it
either becomes a one or a zero, so you can you bitwise operators as if
they were logical operators:

bool a = 5, b = 6;

if (a == b) DoSomething; /* This will execute */

What type is commonly used in C for playing around with boolean
values?

int a = 5, b = 6;

if (!a == !b) DoSomething; /* This will execute */
 
I

Ian Collins

Martin said:
I'm writing code for an embedded systems project so I'll *really* have
to watch how much memory I'm using... so would it be wise to be
returning "int" from functions that I would otherwise (in C++) return
a bool from? For example


I suppose I'm asking two questions:

a) What type is commonly used for booleans?
b) What type is commonly used for booleans when you've to go easy
on memory consumption?

In that case, if I didn't have access to a C99 compiler, or a compiler
with bool as an extension, I'd use an enum. Most embedded compilers I
have used have options to minimise the size of enums by using the
smallest type than holds the range of the enum values.
 
U

user923005

I come from C++, and there's a type called "bool" in C++. It works
exactly like any other integer type except that when promoted, it
either becomes a one or a zero, so you can you bitwise operators as if
they were logical operators:

bool a = 5, b = 6;

if (a == b) DoSomething; /* This will execute */

What type is commonly used in C for playing around with boolean
values?

I'm writing code for an embedded systems project so I'll *really* have
to watch how much memory I'm using... so would it be wise to be
returning "int" from functions that I would otherwise (in C++) return
a bool from? For example

int QueryBit(char unsigned const *const pc, unsigned const index)
{
return *pc & (1U << index);

}

(Let's leave alone for the moment the issue of whether this should
instead be a macro)

I suppose I'm asking two questions:

a) What type is commonly used for booleans?
b) What type is commonly used for booleans when you've to go easy
on memory consumption?

If you have C99 {where _Bool is a type} then:

ISO/IEC 9899:1999 (E) ©ISO/IEC
7.16 Boolean type and values <stdbool.h>
1 The header <stdbool.h> defines four macros.
2 The macro
bool
expands to _Bool.
3 The remaining three macros are suitable for use in #if preprocessing
directives. They are:
true
which expands to the integer constant 1,
false
which expands to the integer constant 0, and
_ _bool_true_false_are_defined
which expands to the integer constant 1.
4 Notwithstanding the provisions of 7.1.3, a program may undefine and
perhaps then redefine the macros bool, true, and false.213)
213) See "future library directions" (7.26.7).
252 Library §7.16

Else just use enums or macros. Typically as enum:

typedef boolean_type {false=0, true} bool_t;

Typically as macro:

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE !FALSE
#endif
 
K

Keith Thompson

Martin Wells said:
I come from C++, and there's a type called "bool" in C++. It works
exactly like any other integer type except that when promoted, it
either becomes a one or a zero, so you can you bitwise operators as if
they were logical operators:

bool a = 5, b = 6;

if (a == b) DoSomething; /* This will execute */

What type is commonly used in C for playing around with boolean
values?

I'm writing code for an embedded systems project so I'll *really* have
to watch how much memory I'm using... so would it be wise to be
returning "int" from functions that I would otherwise (in C++) return
a bool from?
[...]

Using a type smaller than int for booleans is likely to save space,
but is also likely (but not certain) to increase code size. If your
CPU can load, store, and manipulate bytes as easily as words, using a
1-byte type makes sense; if not, int is likely to be a good choice.

If you want to have, say, large arrays of booleans, the tradeoffs
change. It might even make sense to store a boolean value in each bit
(but you'll have to write your own bitwise masking and shifting code
to do this -- or find something that's already been written).

Assuming C99's _Bool is not available, my favorite form is something
like:

typedef enum { false, true } bool;

This allows the compiler to decide how big to make a bool. But watch
out for name collisions if another library you're using defines its
own boolean type.
 
M

Martin Ambuhl

Martin said:
I come from C++, and there's a type called "bool" in C++. It works
exactly like any other integer type except that when promoted, it
either becomes a one or a zero, so you can you bitwise operators as if
they were logical operators:

bool a = 5, b = 6;

if (a == b) DoSomething; /* This will execute */

What type is commonly used in C for playing around with boolean
values?

It used to be that C programmers did not rely on the boolean crutch,
since various kinds of integers serve quite well without losing
information. However, for some reason this expensive way to store
single bits has enough appeal that we now have:

#include <stdbool.h>
#include <stdio.h>

int main(void)
{
bool a_bool = 5, b_bool = 6; /* <stdbool.h> causes 'bool' to
expand to '_Bool' */
_Bool a_Bool = 5, b_Bool = 6;
unsigned int a_int = 5, b_int = 6;

printf("using 'bool' versions of a and b\n"
"a_bool = %u, compares %sequal to 'true'\n"
"b_bool = %u, compares %sequal to 'true'\n"
"the value of a_bool == b_bool is %u\n"
"the value of (a_bool == b_bool) == true is %u\n\n",
a_bool, (a_bool == true) ? "" : "not ",
b_bool, (b_bool == true) ? "" : "not ",
a_bool == b_bool, (a_bool == b_bool) == true);


printf("using '_Bool' versions of a and b\n"
"a_Bool = %u, compares %sequal to 'true'\n"
"b_Bool = %u, compares %sequal to 'true'\n"
"the value of a_Bool == b_Bool is %u\n"
"the value of (a_Bool == b_Bool) == true is %u\n\n",
a_Bool, (a_Bool == true) ? "" : "not ",
b_Bool, (b_Bool == true) ? "" : "not ",
a_Bool == b_Bool, (a_Bool == b_Bool) == true);

printf("using 'unsigned int' versions of a and b\n"
"a_bool = %u, compares %sequal to 'true'\n"
"b_bool = %u, compares %sequal to 'true'\n"
"the value of a_int == b_int is %u\n"
"the value of (a_int == b_int) == true is %u\n\n",
a_int, (a_int == true) ? "" : "not ",
b_int, (b_int == true) ? "" : "not ",
a_int == b_int, (a_int == b_int) == true);

return 0;
}

[output]
using 'bool' versions of a and b
a_bool = 1, compares equal to 'true'
b_bool = 1, compares equal to 'true'
the value of a_bool == b_bool is 1
the value of (a_bool == b_bool) == true is 1

using '_Bool' versions of a and b
a_Bool = 1, compares equal to 'true'
b_Bool = 1, compares equal to 'true'
the value of a_Bool == b_Bool is 1
the value of (a_Bool == b_Bool) == true is 1

using 'unsigned int' versions of a and b
a_bool = 5, compares not equal to 'true'
b_bool = 6, compares not equal to 'true'
the value of a_int == b_int is 0
the value of (a_int == b_int) == true is 0
 
C

CBFalconer

Martin said:
I come from C++, and there's a type called "bool" in C++. It works
exactly like any other integer type except that when promoted, it
either becomes a one or a zero, so you can you bitwise operators
as if they were logical operators:

There is no boolean type in C90. C99 has a _Bool type.
.... snip ...

I suppose I'm asking two questions:

a) What type is commonly used for booleans?
b) What type is commonly used for booleans when you've to
go easy on memory consumption?
From N869:

[#6] For each of the signed integer types, there is a
corresponding (but different) unsigned integer type
(designated with the keyword unsigned) that uses the same
amount of storage (including sign information) and has the
same alignment requirements. The type _Bool and the
unsigned integer types that correspond to the standard
signed integer types are the standard unsigned integer
types. The unsigned integer types that correspond to the
extended signed integer types are the extended unsigned
integer types. The standard and extended unsigned integer
types are collectively called unsigned integer types.27)

If you #include <stdbool.h> then bool is defined (as _Bool), and:

B.15 Boolean type and values <stdbool.h>

bool
true
false
__bool_true_false_are_defined

Note that this is only in C99.
 
A

Ark Khasin

Ian said:
In that case, if I didn't have access to a C99 compiler, or a compiler
with bool as an extension, I'd use an enum. Most embedded compilers I
have used have options to minimise the size of enums by using the
smallest type than holds the range of the enum values.
I tried and adopted enum until I got a new version of the compiler that
supported _Bool. To my astonishment, _Bool generated much more efficient
code than the enum.
Still, honestly, there are very few precious cases where bool of any
sort has merits. They AFAIK are limited to temporarily storing results
of bulky comparisons and used only to improve readability (since the
compiler should optimize them out).
bool return type looks evil since the compiler effectively does
something like return !!x; it's an overhead I could do without.
-- Ark
 
P

Peter J. Holzer

I come from C++, and there's a type called "bool" in C++. It works
exactly like any other integer type except that when promoted, it
either becomes a one or a zero, so you can you bitwise operators as if
they were logical operators:

bool a = 5, b = 6;

if (a == b) DoSomething; /* This will execute */

What type is commonly used in C for playing around with boolean
values?

I'm writing code for an embedded systems project so I'll *really* have
to watch how much memory I'm using... so would it be wise to be
returning "int" from functions that I would otherwise (in C++) return
a bool from? For example

int QueryBit(char unsigned const *const pc, unsigned const index)
{
return *pc & (1U << index);
}

Worrying about the memory consumption of return types is probably
futile. On most systems the return value is passed in a register (if it
fits), so it always takes the same space and that space isn't in memory.

Also worrying about the size of simple variables probably doesn't make
much sense unless you really have a lot of them or are making heavy use
of recursive functions.

Where is the size really matters is in arrays. Storing boolean values in
an int[] wastes a lot of space (probably 15 or 31 bits per value,
depending on your platform). By using bool (if available), enum or char,
you may be able to reduce the overhead to 7 bits per value. But an array
element can never use less than 8 bits in C, so if that's still too
much, you should consider storing them in an array of unsigned int,
where each element holds the appropriate number of bits.


hp
 
M

Malcolm McLean

Martin Wells said:
What type is commonly used in C for playing around with boolean
values?

a) What type is commonly used for booleans?
b) What type is commonly used for booleans when you've to go easy
on memory consumption?
int by convention.

So

int is_prime(int N)

for instance.

Not

typedef int BOOL;

BOOL is_prime(int N)

bool breaks libraries. You don't want everyone who happens to cut and paste
your is_prime function to be tied to BOOL throughout his code.

However unsigned char would work. (A pathological implementation could make
1 a trap value for characters).

Space is only a problem when you need several booleans on the go - eg an
array of a thousand of the things.

Method 1: use a bitfield. This will often save the most. Typically there
will be a integer field that doesn't need the full 32 bits and you can raid
for the boolean, thus giving you a zero memory footprint.
Method 2: use unsigned char for the array, convert to in the minute you read
and write it. This is very simple and fast.
Method 3: write a getbit() and setbit() function to manage a flat array of
unsigned chars. This is a nuisance, but gives you total control, over bit
packing. It will probably be slightly slower than the bitfield, and
considerably slower than the char array.
Method 4: (for the crazed). Typically you can compress a bitstream. This
will really squeeze down your memory take, at a cost of massive overhead.
 
A

Army1987

Typically as macro:

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE !FALSE
What's wrong with
#define TRUE 1
? If you want to do that, put parentheses at least, so that, er...
TRUE[arr] will do the right thing... :)
 
P

pete

Malcolm said:
Method 3: write a getbit() and setbit()
function to manage a flat array of unsigned chars.
This is a nuisance, but gives you total control, over bit
packing. It will probably be slightly slower than the bitfield, and
considerably slower than the char array.

I use macros. The last time that I tried to use a bitfield,
about ten years ago, the bitfield was much slower.
/*
** Some bitwise macros for unsigned U
*/
#define READ_UBIT(U, N) ((U) >> (N) & 1u)
#define FLIP_UBIT(U, N) ((void)((U) ^= 1u << (N)))
#define SET_UBIT(U, N) ((void)((U) |= 1u << (N)))
#define CLEAR_UBIT(U, N) ((void)((U) &= ~(1u << (N))))
 
R

Roberto Waltman

Martin Wells said:
I come from C++, and there's a type called "bool"
...
a) What type is commonly used for booleans?

I use bool, (partially because some of my code must be written in the
mythical C/C++ language):

#ifndef __cplusplus
typedef enum
{
false = 0,
true = !false
} bool;
#endif /* __cplusplus */
b) What type is commonly used for booleans when you've to go easy
on memory consumption?

That depends on the compiler and target processor. A C compiler for
the 8051 architecture, for example, could use single bits without any
additional masking and shifting code.
If you have a very large number of booleans, a library providing bit
vector operations on a char array is probably a good choice.
 
K

Keith Thompson

Malcolm McLean said:
However unsigned char would work. (A pathological implementation could
make 1 a trap value for characters).

No, it couldn't. (I assume that by "characters" you mean values of
type 'char' and 'signed char'.)

There's no such thing as a "trap value"; there are only trap
representations. All three character types are guaranteed to be able
to represent the values 0 and 1 (in fact, they're all guaranteed to be
able to represent any values in the range 0..127).

Using plain char lets the compiler choose whichever representation,
signed or unsigned, gives the best performance (though there's no
guarantee that the compiler actually makes its choice based on
performane).

But if you're only dealing with singleton objects and values, int is
probably the best choice.
 
K

Keith Thompson

Roberto Waltman said:
I use bool, (partially because some of my code must be written in the
mythical C/C++ language):

#ifndef __cplusplus
typedef enum
{
false = 0,
true = !false
} bool;
#endif /* __cplusplus */

That's more complicated than it needs to be; you're telling the
compiler things it already knows. Using !false rather than just 1
buys you nothing; there's no chance that the value of !false will ever
be anything other than 1. And specifying *any* values is superfluous;
the language guarantees that the values will be 0 and 1, respectively.

typedef enum { false, true } bool;

is entirely adequate, though I *might* write:

typedef enum { false=0, true=1 } bool;

just for emphasis.

In fact, here's what I might do (if I really wanted compatibility with
both C and C++):

#ifdef __cplusplus
/* bool, false, and true are predefined. */
#elif __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#else
typedef enum { false, true } bool;
#endif

Note that C99's 'bool' has certain properties that the enum type lacks
(and C++'s 'bool'probably does too); you just have to carefully write
your code to avoid excercising any of the differences.
That depends on the compiler and target processor. A C compiler for
the 8051 architecture, for example, could use single bits without any
additional masking and shifting code.

But an 8051 C compiler would have to be fairly clever to generate code
that accesses single-bit objects, since there's no really good way to
specify that in standard C. Or perhaps the compiler could provide
single-bit objects as an extension. Quite possibly compilers already
do this.
If you have a very large number of booleans, a library providing bit
vector operations on a char array is probably a good choice.

Agreed.
 
R

Roberto Waltman

Keith Thompson said:
That's more complicated than it needs to be; you're telling the
compiler things it already knows. Using !false rather than just 1
buys you nothing; there's no chance that the value of !false will ever
be anything other than 1. And specifying *any* values is superfluous;
the language guarantees that the values will be 0 and 1, respectively.

typedef enum { false, true } bool;

is entirely adequate, though I *might* write:

typedef enum { false=0, true=1 } bool;

just for emphasis.

Correct, of course, but I would not use the first version.
I worked on a few projects with coding standards that required to
provide values to all enums, instead of relying on the compiler
default handling. It made sense there, to give one example, with more
than a hundred values for an enum used for function error return
codes, separated in ranges for each subsystem. We did not want values
to change when new error codes were added. On top of that, in some
cases it may be desirable to be able to change the order of the
declarations, without changing their value (group all fatal errors
together, etc.):

typedef enum
{
...
STAT_COMMS_OK = 0x1000;
STAT_COMMS_LINK_DOWN = 0x1001;
STAT_COMMS_BAD_CRC = 0x1002
...
STAT_DB_OK = 0x2000;
STAT_DB_BAD_OID = 0x2001;
... /* etc. */
} STATUS;

I have adopted that practice and, for consistency, I use even in
obvious cases like the enum above. The !false instead of 1 is to
emphasize these are logical values. (Personal taste only, will not
defend this very vigorously.)
...
But an 8051 C compiler would have to be fairly clever to generate code
that accesses single-bit objects, since there's no really good way to
specify that in standard C. Or perhaps the compiler could provide
single-bit objects as an extension. Quite possibly compilers already
do this.

Just checked the online documentation for Keil's CX51 compiler.
It provides a 'bit' data type as a language extension. (With some
limitations: it is not possible to declare a bit array, or a pointer
to a bit variable. The number of bit variables is limited to 128 by
the size of the 8051's internal bit addressable memory)
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top