Reputation: 55559
C doesn't have any built-in Boolean types. What's the best way to use them in C?
Upvotes: 878
Views: 1638947
Reputation: 51389
bool
and _Bool
, and true
and false
are language keywords for boolean types. bool
/_Bool
is a type that can hold either the value true
or false
. Logical operators !
, ||
, and &&
can be used.
A scalar-typed value can be implicitly converted to bool
. Zero-valued arithmetic types convert to false
, as well as null
pointers, or anything of type nullptr_t
. Any other scalar-type values convert to true
. Rules for promotion to higher-rank integer types can be found here.
The macros bool
, true
, and false
from <stdbool.h>
are "removed" (from that header specifically), but an implementation can still define such predefined macros for compatibility, and implementations can still use macros to implement them, and if that is done, programs can still undefine and redefine them. The macro __bool_true_false_are_defined
is deprecated.
See also https://open-std.org/JTC1/SC22/WG14/www/docs/n2935.pdf.
_Bool
is a language keyword for a boolean type that can hold either the value 1
or 0
. Logical operators !
, ||
, and &&
can be used.
When converting scalar types to _Bool
, any value that compares equal to zero is converted to 0
, and other value is converted to 1
. Rules for promotion to higher-rank integer types can be found here.
The standard header <stdbool.h>
provides a convenience macro that defines bool
as an alias to _Bool
, a macro true
that expands to the integer-type (not _Bool
!) constant 1
, a macro false
that expands to the integer constant 0
, and a macro __bool_true_false_are_defined
that expands to the integer constant 1
. Programs are allowed to undefine and redefine the macros bool
, true
, and false
.
You could write something like typedef enum { false, true } bool;
.
Upvotes: 3
Reputation: 2208
This is just a complement to other answers and some clarification, if you are allowed to use C99.
+-------+----------------+-------------------------+--------------------+
| Name | Characteristic | Dependence in stdbool.h | Value |
+-------+----------------+-------------------------+--------------------+
| _Bool | Native type | Don't need header | |
+-------+----------------+-------------------------+--------------------+
| bool | Macro | Yes | Translate to _Bool |
+-------+----------------+-------------------------+--------------------+
| true | Macro | Yes | Translate to 1 |
+-------+----------------+-------------------------+--------------------+
| false | Macro | Yes | Translate to 0 |
+-------+----------------+-------------------------+--------------------+
Some of my preferences:
_Bool
or bool
? Both are fine, but bool
looks better than the keyword _Bool
.bool
and _Bool
are: false
or true
. Assigning 0
or 1
instead of false
or true
is valid, but is harder to read and understand the logic flow.Some information from the standard:
_Bool
is not unsigned int
, but is part of the group unsigned integer types. It is large enough to hold the values 0
or 1
.bool
true
and false
but sure is not a good idea. This ability is considered obsolescent and will be removed in future._Bool
or bool
, if the scalar value is equal to 0
or compares to 0
it will be 0
, otherwise the result is 1
: _Bool x = 9;
9
is converted to 1
when assigned to x
._Bool
is 1 byte (8 bits), usually the programmer is tempted to try to use the other bits, but is not recommended, because the only guaranteed that is given is that only one bit is use to store data, not like type char
that have 8 bits available.Upvotes: 8
Reputation: 10073
Here is the version that I used:
typedef enum { false = 0, true = !false } bool;
Because false only has one value, but a logical true could have many values, but technique sets true to be what the compiler will use for the opposite of false.
This takes care of the problem of someone coding something that would come down to this:
if (true == !false)
I think we would all agree that that is not a good practice, but for the one time cost of doing "true = !false" we eliminate that problem.
[EDIT] In the end I used:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
to avoid name collision with other schemes that were defining true
and false
. But the concept remains the same.
[EDIT] To show conversion of integer to boolean:
mybool somebool;
int someint = 5;
somebool = !!someint;
The first (right most) ! converts the non-zero integer to a 0, then the second (left most) ! converts the 0 to a myfalse
value. I will leave it as an exercise for the reader to convert a zero integer.
[EDIT]
It is my style to use the explicit setting of a value in an enum when the specific value is required even if the default value would be the same. Example: Because false needs to be zero I use false = 0,
rather than false,
[EDIT] Show how to limit the size of enum when compiling with gcc:
typedef __attribute__((__packed__)) enum { myfalse = 0, mytrue = !myfalse } mybool;
That is, if someone does:
struct mystruct {
mybool somebool1;
mybool somebool2;
mybool somebool3;
mybool somebool4;
}
the size of the structure will be 4 bytes rather than 16 bytes.
Upvotes: 85
Reputation: 44812
From best to worse:
Option 1 (C99 and newer)
#include <stdbool.h>
Option 2
typedef enum { false, true } bool;
Option 3
typedef int bool;
enum { false, true };
Option 4
typedef int bool;
#define true 1
#define false 0
If you are undecided, go with #1!
Upvotes: 1281
Reputation:
This is what I use:
enum {false, true};
typedef _Bool bool;
_Bool
is a built in type in C. It's intended for boolean values.
Upvotes: 1
Reputation: 134038
First things first. C, i.e. ISO/IEC 9899 has had a boolean type for 19 years now. That is way longer time than the expected length of the C programming career with amateur/academic/professional parts combined when visiting this question. Mine does surpass that by mere perhaps 1-2 years. It means that during the time that an average reader has learnt anything at all about C, C actually has had the boolean data type.
For the datatype, #include <stdbool.h>
, and use true
, false
and bool
. Or do not include it, and use _Bool
, 1
and 0
instead.
There are various dangerous practices promoted in the other answers to this thread. I will address them:
typedef int bool;
#define true 1
#define false 0
This is no-no, because a casual reader - who did learn C within those 19 years - would expect that bool
refers to the actual bool
data type and would behave similarly, but it doesn't! For example
double a = ...;
bool b = a;
With C99 bool
/ _Bool
, b
would be set to false
iff a
was zero, and true
otherwise. C11 6.3.1.2p1
- When any scalar value is converted to
_Bool
, the result is 0 if the value compares equal to 0; otherwise, the result is 1. 59)Footnotes
59) NaNs do not compare equal to 0 and thus convert to 1.
With the typedef
in place, the double
would be coerced to an int
- if the value of the double isn't in the range for int
, the behaviour is undefined.
Naturally the same applies to if true
and false
were declared in an enum
.
What is even more dangerous is declaring
typedef enum bool {
false, true
} bool;
because now all values besides 1 and 0 are invalid, and should such a value be assigned to a variable of that type, the behaviour would be wholly undefined.
Therefore iff you cannot use C99 for some inexplicable reason, for boolean variables you should use:
int
and values 0
and 1
as-is; and carefully do domain conversions from any other values to these with double negation !!
BOOL
, TRUE
and FALSE
!Upvotes: 50
Reputation: 90155
Conditional expressions are considered to be true if they are non-zero, but the C standard requires that logical operators themselves return either 0 or 1.
@Tom: #define TRUE !FALSE is bad and is completely pointless. If the header file makes its way into compiled C++ code, then it can lead to problems:
void foo(bool flag);
...
int flag = TRUE;
foo(flag);
Some compilers will generate a warning about the int => bool conversion. Sometimes people avoid this by doing:
foo(flag == TRUE);
to force the expression to be a C++ bool. But if you #define TRUE !FALSE, you end up with:
foo(flag == !0);
which ends up doing an int-to-bool comparison that can trigger the warning anyway.
Upvotes: 2
Reputation: 79
You can simply use the #define
directive as follows:
#define TRUE 1
#define FALSE 0
#define NOT(arg) (arg == TRUE)? FALSE : TRUE
typedef int bool;
And use as follows:
bool isVisible = FALSE;
bool isWorking = TRUE;
isVisible = NOT(isVisible);
and so on
Upvotes: -4
Reputation: 6173
Nowadays C99 supports boolean types but you need to #include <stdbool.h>
.
Example:
#include <stdbool.h>
int main()
{
bool arr[2] = {true, false};
printf("%d\n", arr[0] && arr[1]);
printf("%d\n", arr[0] || arr[1]);
return 0;
}
Output:
0
1
Upvotes: 3
Reputation: 67
If you are using C99 then you can use the _Bool
type. No #include
s are necessary. You do need to treat it like an integer, though, where 1
is true
and 0
is false
.
You can then define TRUE
and FALSE
.
_Bool this_is_a_Boolean_var = 1;
//or using it with true and false
#define TRUE 1
#define FALSE 0
_Bool var = TRUE;
Upvotes: 1
Reputation: 93
You could use _Bool, but the return value must be an integer (1 for true, 0 for false). However, It's recommended to include and use bool as in C++, as said in this reply from daniweb forum, as well as this answer, from this other stackoverflow question:
_Bool: C99's boolean type. Using _Bool directly is only recommended if you're maintaining legacy code that already defines macros for bool, true, or false. Otherwise, those macros are standardized in the header. Include that header and you can use bool just like you would in C++.
Upvotes: 2
Reputation: 36327
You can use a char, or another small number container for it.
Pseudo-code
#define TRUE 1
#define FALSE 0
char bValue = TRUE;
Upvotes: 1
Reputation: 16470
A few thoughts on booleans in C:
I'm old enough that I just use plain int
s as my boolean type without any typedefs or special defines or enums for true/false values. If you follow my suggestion below on never comparing against boolean constants, then you only need to use 0/1 to initialize the flags anyway. However, such an approach may be deemed too reactionary in these modern times. In that case, one should definitely use <stdbool.h>
since it at least has the benefit of being standardized.
Whatever the boolean constants are called, use them only for initialization. Never ever write something like
if (ready == TRUE) ...
while (empty == FALSE) ...
These can always be replaced by the clearer
if (ready) ...
while (!empty) ...
Note that these can actually reasonably and understandably be read out loud.
Give your boolean variables positive names, ie full
instead of notfull
. The latter leads to code that is difficult to read easily. Compare
if (full) ...
if (!full) ...
with
if (!notfull) ...
if (notfull) ...
Both of the former pair read naturally, while !notfull
is awkward to read even as it is, and becomes much worse in more complex boolean expressions.
Boolean arguments should generally be avoided. Consider a function defined like this
void foo(bool option) { ... }
Within the body of the function, it is very clear what the argument means since it has a convenient, and hopefully meaningful, name. But, the call sites look like
foo(TRUE);
foo(FALSE):
Here, it's essentially impossible to tell what the parameter meant without always looking at the function definition or declaration, and it gets much worse as soon if you add even more boolean parameters. I suggest either
typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);
or
#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }
In either case, the call site now looks like
foo(OPT_ON);
foo(OPT_OFF);
which the reader has at least a chance of understanding without dredging up the definition of foo
.
Upvotes: 290
Reputation: 52598
If you are using a C99 compiler it has built-in support for bool types:
#include <stdbool.h>
int main()
{
bool b = false;
b = true;
}
http://en.wikipedia.org/wiki/Boolean_data_type
Upvotes: 54
Reputation: 19702
A boolean in C is an integer: zero for false and non-zero for true.
See also Boolean data type, section C, C++, Objective-C, AWK.
Upvotes: 90
Reputation: 35654
C has a boolean type: bool (at least for the last 10(!) years)
Include stdbool.h and true/false will work as expected.
Upvotes: 14
Reputation: 3443
Anything nonzero is evaluated to true in boolean operations, so you could just
#define TRUE 1
#define FALSE 0
and use the constants.
Upvotes: 13