C does not provide a standard boolean type, because picking one
involves a space/time tradeoff which is best decided by the
programmer. (Using an int
for a boolean may be faster, while
using char
may save data space.)
The choice between #defines and enums is arbitrary and not terribly interesting (see also question 9.1). Use any of
#define TRUE 1 #define YES 1 #define FALSE 0 #define NO 0 enum bool {false, true}; enum bool {no, yes};
or use raw 1 and 0, as long as you are consistent within one
program or project. (An enum may be preferable if your debugger
expands enum
values when examining variables.)
Some people prefer variants like
#define TRUE (1==1) #define FALSE (!TRUE)
or define "helper" macros such as
#define Istrue(e) ((e) != 0)
These don't buy anything (see question 8.2 below; see also question 1.6).
TRUE
to be 1 dangerous, since any nonzero value
is considered "true" in C? What if a built-in boolean or
relational operator "returns" something other than 1?
It is true (sic) that any nonzero value is considered true in C, but this applies only "on input", i.e. where a boolean value is expected. When a boolean value is generated by a built-in operator, it is guaranteed to be 1 or 0. Therefore, the test
if((a == b) == TRUE)
will work as expected (as long as TRUE
is 1), but it is
obviously silly. In general, explicit tests against TRUE
and
FALSE
are undesirable, because some library functions (notably
isupper, isalpha, etc.) return, on success, a nonzero value
which is not necessarily 1. (Besides, if you believe that
"if((a == b) == TRUE)
" is an improvement over "if(a == b)", why
stop there? Why not use "if(((a == b) == TRUE) == TRUE)
"?) A
good rule of thumb is to use TRUE
and FALSE
(or the like) only
for assignment to a Boolean variable or function parameter, or as the
return value from a Boolean function, but never in a comparison.
The preprocessor macros TRUE
and FALSE
are used for code
readability, not because the underlying values might ever
change. (See also questions 1.7 and 1.9.)
References: K&R I Sec. 2.7 p. 41; K&R II Sec. 2.6 p. 42, Sec. A7.4.7 p. 204, Sec. A7.9 p. 206; ANSI Secs. 3.3.3.3, 3.3.8, 3.3.9, 3.3.13, 3.3.14, 3.3.15, 3.6.4.1, 3.6.5; Achilles and the Tortoise.