If the _Bool type acts like an integer and doesn't enforce that a value is true/false or 1/0, for example:
_Bool bools[] = {0,3,'c',0x17};
printf("%d", bools[2]);
> 1
What is the advantage of having that there? Is it just a simple way to coerce things to see how they would evaluate for 'truth-ness', for example:
printf("%d\n", (_Bool) 3);
> 1
Or how is this helpful or useful in the C language?
What advantage does _Bool give?
The value of a _Bool is either 0 or 1. Nothing else, unlike an int.
Conversion to a _Bool always converts non-zero to 1 and only 0 to 0.
When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.
Examples:
#include <math.h>
#include <stdlib.h>
_Bool all_false[] = { 0, 0.0, -0.0, NULL };
_Bool all_true[] = { 13, 0.1, 42.0, "Hello", NAN };
Notice the difference of conversion/casting to int vs; _Bool: (int) 0.1 --> 0, yet (_Bool) 0.1 --> 1.
Notice the difference of conversion/casting to unsigned vs; _Bool: (unsigned) 0x100000000 --> 0, yet (_Bool) 0x100000000 --> 1.
_Bool adds clarity to boolean operations.
_Bool is a distinctive type from int, char, etc. when used with _Generic.
Prior to C99, C lacked _Bool. Much early code formed their own types bool, Bool, boolean, bool8, bool_t, .... Creating a new type _Bool brought uniformity to this common, yet non-uniform practice. <stdbool.h> is available to use bool, true, false. This allows older code, which does not include <stdbool.h> to not break, yet newer code to use cleaner names.
OP's example with "doesn't enforce that a value is true/false or 1/0" does enforce that bools[2] had a value of 1. It did not enforce that the initializer of 'c', an int, had to be in the range of [0...1] nor of type _Bool, much like int x = 12.345; is allowed. In both cases, a conversion occurred. Although the 2nd often generates a warning.
The advantage is legibility, nothing more. For example:
bool rb() {
if (cond && f(y)) {
return true;
}
return false;
}
Versus:
int rb() {
if (cond && f(y)) {
return 1;
}
return 0;
}
There's really no other benefit to it. For those that are used to working in C code without bool, it's largely cosmetic, but for those used to C++ and its bool it may make coding feel more consistent.
As always, an easy way to "cast to a boolean value" is just double negation, like:
!!3
Where that will reduce it to a 0 or 1 value.
Consider this:
(bool) 0.5 -> 1
( int) 0.5 -> 0
As you can see, _Bool does not act like an integer.
Related
C doesn't have any built-in boolean types. What's the best way to use them in C?
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
Explanation
Option 1 will work only if you use C99 (or newer) and it's the "standard way" to do it. Choose this if possible.
Options 2, 3 and 4 will have in practice the same identical behavior. #2 and #3 don't use #defines though, which in my opinion is better.
If you are undecided, go with #1!
A few thoughts on booleans in C:
I'm old enough that I just use plain ints 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.
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.
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.
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
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:
type int and values 0 and 1 as-is; and carefully do domain conversions from any other values to these with double negation !!
or if you insist you don't remember that 0 is falsy and non-zero truish, at least use upper case so that they don't get confused with the C99 concepts: BOOL, TRUE and FALSE!
typedef enum {
false = 0,
true
} t_bool;
C has a boolean type: bool (at least for the last 10(!) years)
Include stdbool.h and true/false will work as expected.
Anything nonzero is evaluated to true in boolean operations, so you could just
#define TRUE 1
#define FALSE 0
and use the constants.
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.
Accepted values for 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 info 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.
DO NOT, but yes, you are able to redefine bool true and false but sure is not a good idea. This ability is considered obsolescent and will be removed in future.
Assigning an scalar type (arithmetic types and pointer types) to _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.
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
It is this:
#define TRUE 1
#define FALSE 0
You can use a char, or another small number container for it.
Pseudo-code
#define TRUE 1
#define FALSE 0
char bValue = TRUE;
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++.
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.
If you are using C99 then you can use the _Bool type. No #includes 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;
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.
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
Traditionally, Boolean values in C were represented with int or char. The new _Bool type makes intent clearer, but also has another interesting feature: it seems casting floating-point numbers to it, does not truncate toward zero, but compares with exact zero:
#include <stdio.h>
int main(int argc, char **argv) {
double a = 0.1;
int i = (int)a;
printf("%d\n", i);
_Bool b = (_Bool)a;
printf("%d\n", b);
return 0;
}
prints
0
1
So this is a semantic difference. And one I'm happy with; it duplicates the effect of using a floating-point number as a conditional.
Is this something that can be depended on across-the-board? Does the new C standard define the result of casting X to _Bool as identical to X ? 1 : 0 for all X for which that is a valid operation?
In the C Standard (6.3.1.2 Boolean type) there is written
1 When any scalar value is converted to _Bool, the result is 0 if the
value compares equal to 0; otherwise, the result is 1.
That is during conversion to the type _Bool the compiler does not try to represent the value (truncating toward zero or something else) of the operand of an expression with the casting operator as an integer. It only checks whether the value is equal or unequal to zero.
Actually this declaration
_Bool b = (_Bool)a;
is equivalent to
_Bool b = a;
It is entirely consistent, a non-zero value implicitly cast to _Bool is true. Since _Bool is a true Boolean type and not "faked", it can behave correctly. So:
_Bool b = (_Bool)a ;
is equivalent to:
_Bool b = (a == 0) ;
not:
_Bool b = ((int)a == 0) ;
In the end interpreting a float as Boolean is nonsense and ill-advised as is comparing it for equality to zero. If you want the semantic you expect, you must code it explicitly:
_Bool b = (_Bool)((int)a);
Semantically that is equivalent to :
_Bool b = (a < 1.0);
It is clearer and safer to use a Boolean expression than to force a value to Boolean with a cast.
I would like try to understand how is working the compilator when we compare an enumerate with invalid value, and what the program is doing during execution.
I found strange source code during my work, and did not understand the behaviour of the program, which was not giving me the expected result.
I wrote the following little program to summarize my problem.
I create an enum E_Number and I instanciate a variable a, with the value -1.
Then I perform comparison on a to check if it belongs to the range of the enum.
(I know, this is really strange, but this is exactly what i found in source code !)
I expected the result tells me Not in range because of the fail of the first condition (a >= FIRST_ENUM).
But it was the fail of the second condition (a < NB_MAX_NUMBER) which gave me the right result (see the printf())...
If I cast a in (int) in the if conditions, I get excepted results.
So what is happening during the execution ? Is the program considering -1 as an other possible enum value which will be positionned after NB_MAX_NUMBER ? What is the rule for > and < operator on enum ?
#include <stdio.h>
#define FIRST_ENUM 0
typedef enum{
NUM_1 = FIRST_ENUM,
NUM_2,
NUM_3,
NB_MAX_NUMBER
}E_Number;
int main()
{
E_Number a = -1;
if ((a >= FIRST_ENUM) && (a < NB_MAX_NUMBER))
{
printf("In Range\n");
}
else
{
printf("Not in Range\n");
}
printf("1st condition = %s\n", (a >= FIRST_ENUM)?"TRUE":"FALSE");
printf("2nd condition = %s\n", (a < NB_MAX_NUMBER)?"TRUE":"FALSE");
return 0;
}
gcc program.c
.\a.exe
Not in Range
1st condition = TRUE
2nd condition = FALSE
I am working with MINGW compilator ( gcc (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 4.9.2 )
In your case the compiler consider E_Number as unsigned int because all the legal values are unsigned, so -1 is considered to be ~0u which is >= FIRST_ENUM and < NB_MAX_NUMBER
I have the same behavior with gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1+deb9u1)
pi#raspberrypi:~ $ ./a.out
Not in Range
1st condition = TRUE
2nd condition = FALSE
But, if I change your definitions like that :
#include <stdio.h>
#define FIRST_ENUM -1
typedef enum{
NUM_1 = FIRST_ENUM,
NUM_2,
NUM_3,
NB_MAX_NUMBER
}E_Number;
int main()
{
E_Number a = -2;
if ((a >= FIRST_ENUM) && (a < NB_MAX_NUMBER))
{
printf("In Range\n");
}
else
{
printf("Not in Range\n");
}
printf("1st condition = %s\n", (a >= FIRST_ENUM)?"TRUE":"FALSE");
printf("2nd condition = %s\n", (a < NB_MAX_NUMBER)?"TRUE":"FALSE");
return 0;
}
the behavior change and the enum is considered to be an int and I have :
pi#raspberrypi:~ $ ./a.out
Not in Range
1st condition = FALSE
2nd condition = TRUE
Enumarator constants are of type int. The enumerator type is an unspecified integer type capable of representing all the enumerator constants.
6.7.2.2p4:
Each enumerated type shall be compatible with char, a signed integer
type, or an unsigned integer type. The choice of type is
implementation-defined,128) but shall be capable of representing the
values of all the members of the enumeration. The enumerated type is
incomplete until immediately after the } that terminates the list of
enumerator declarations, and complete thereafter.
Since you haven't enumerated any negative values, that type may well be an unsigned type. If it is, then (E_Number)some_integer will always be greater than or equal to zero (0==FIRST_ENUM).
If you expand the enum list to:
typedef enum{
NUM_NOPE=-1,
NUM_1 = FIRST_ENUM,
NUM_2,
NUM_3,
NB_MAX_NUMBER
}E_Number;
you'll force the compiler to use a signed type and the results will reverse.
Quote from ISO/IEC 9899:1999, 6.7.2.2p3
Each enumerated type shall be compatible with char, a signed integer
type, or an unsigned integer type. The choice of type is
implementation-defined, 108) but shall be capable of representing the
values of all the members of the enumeration.
So, when you declare an enumeration, you cannot be sure a priori about what kind of data will the implementation of C choose to store that variable. Optimisation reasons, the compiler may not choose an integer type on 4 bytes if you store enumeration constants between [-128, +127]. The implementation may choose char to store an enumerated variable, but you cannot be sure. Any integer data type can be chosen as time as it can store all possible values.
TRUE/FALSE is usually defined in C as below. Are these definitions part of C standard which is supported by varies compiler implementations?
#define TRUE 1
#define FALSE 0
No for TRUE or FALSE. Yes for true and false in C99 or later if you include <stdbool.h>.
C99 and C11 define an integral type with Boolean semantics called _Bool, but no actual true/false keywords exist.
The _Bool type is only capable of storing the values 1 and 0. Any value that doesn't compare equal to 0 is converted to 1, and any value comparing equal to 0 is converted to 0.
By including <stdbool.h>, the _Bool type is allowed to be written as bool as with some other languages, and true and false C preprocessor macros are defined to be 1 and 0 respectively.
Before that, it was somewhat of a convenience for someone to define constants like
#define TRUE 1
#define FALSE 0
typedef char BOOL; /* or #define BOOL char */
or sometimes
typedef enum {False, True} BOOL;
Unlike C99, however, both have at least one flaw:
BOOL bClicked = False;
++bClicked, ++bClicked;
if (bClicked == False)
printf ("False\n");
else if (bClicked == True)
printf ("True\n");
else
printf ("Unknown: %d\n", bClicked);
That will print "Unknown: 2" because the defined BOOL type isn't a true Boolean type.
The C99 version:
_Bool bClicked = 0;
++bClicked, ++bClicked;
if (bClicked == 0)
printf ("False\n");
else if (bClicked == 1)
printf ("True\n");
else
printf ("Unknown: %d\n", bClicked);
That will print "True" because _Bool can only store 0 and 1, so incrementing 1 to get 2, which compares as not equal to 0, results in 1.
Of course, most people just use the language to their advantage rather than actually comparing against True/False constants:
if (bClicked)
{
/* True if bClicked does not compare equal to 0 */
}
else
{
/* False */
}
Because of that behavior, there isn't any real need for a Boolean type or true/false constants; they exist purely for indication of intent.
I vaguely remember someone ranting that some Windows API functions return a value of type BOOL, but TRUE and FALSE weren't the only possible return values, so despite returning a value that should have been a simple comparison as in that last bit of code, more comparisons were needed to handle all possible cases. Had there been an actual Boolean type back then, most likely those functions, whatever they are/were would have returned a value of type int instead. A BOOL return type suggests only two values can be returned, but apparently that wasn't the case with those functions, perhaps because there was a third (error) return value.
C doesn't have any built-in boolean types. What's the best way to use them in C?
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
Explanation
Option 1 will work only if you use C99 (or newer) and it's the "standard way" to do it. Choose this if possible.
Options 2, 3 and 4 will have in practice the same identical behavior. #2 and #3 don't use #defines though, which in my opinion is better.
If you are undecided, go with #1!
A few thoughts on booleans in C:
I'm old enough that I just use plain ints 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.
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.
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.
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
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:
type int and values 0 and 1 as-is; and carefully do domain conversions from any other values to these with double negation !!
or if you insist you don't remember that 0 is falsy and non-zero truish, at least use upper case so that they don't get confused with the C99 concepts: BOOL, TRUE and FALSE!
typedef enum {
false = 0,
true
} t_bool;
C has a boolean type: bool (at least for the last 10(!) years)
Include stdbool.h and true/false will work as expected.
Anything nonzero is evaluated to true in boolean operations, so you could just
#define TRUE 1
#define FALSE 0
and use the constants.
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.
Accepted values for 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 info 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.
DO NOT, but yes, you are able to redefine bool true and false but sure is not a good idea. This ability is considered obsolescent and will be removed in future.
Assigning an scalar type (arithmetic types and pointer types) to _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.
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
It is this:
#define TRUE 1
#define FALSE 0
You can use a char, or another small number container for it.
Pseudo-code
#define TRUE 1
#define FALSE 0
char bValue = TRUE;
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++.
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.
If you are using C99 then you can use the _Bool type. No #includes 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;
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.
I would use a C version test to use the builtin C99 boolean type if available or fallback on an ad hoc implementation otherwise.
#include <stdint.h>
#if __STDC_VERSION__ < 199901L
# define bool uint_fast8_t
# define true 1
# define false 0
#else
# include <stdbool.h>
#endif /* __STDC_VERSION__ < 199901L */
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