#define TRUE !FALSE vs #define TRUE 1
ISO C and C99 both define !
like so.
The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int . The expression !E is equivalent to (0==E).
So !0
evaluates to 1
. Given a standards compliant C compiler both your options will have the same result. In addition there's no runtime penalty, compilers will constant fold !0
to 1
at compile time.
If you want to take this to the logical extreme and make no assumptions about what true or false are...
#define TRUE (1==1)
#define FALSE (!TRUE)
This has the advantage of always being true no matter the language. For example, in shell 0 is usually considered "true" or "not an error".
This sort of thing is an anachronism from a time when C did not have an agreed upon standard. For example, the first edition of Code Complete advocates this on page 369. When it was published back in 1993 there was a good chance your C compiler was not going to be ISO compliant and stdbool.h did not exist. "Code Complete" is also intended for the polyglot programmer working in many different languages. Some, like shell and Lisp, define truth differently.
There is no benefit to option 2, as ! 0
is guaranteed by the C standard to evaluate to 1.
Defining TRUE
in that manner is a staple of old sources, presumably in an attempt to follow the style guide that calls for avoiding "magical constants" whenever possible.
#define FALSE 0
#define TRUE 1 // Option 1
#define TRUE !FALSE // Option 2
There is no difference in the values. Both 1
and !0
are constant expressions of type int
with the same value, 1
(by the Standard's definition of the semantics of the !
operator).
There is a possible difference in that the second definition is not properly parenthesized. Remember that macro expansion is performed textually. Expanding an unparenthesized macro in the middle of an expression can lead to operator precedence problems. I've written up a contrived example here.
Since the unary !
operator has very high precedence, you're not likely to run into a problem. The only case I can think of is if you use it as a prefix to the indexing operator. For example, given:
int arr[] = { 10, 20 };
Option 1 gives:
TRUE[arr] == 20
while option 2 gives:
TRUE[arr] == 0
To see why, remember that array indexing is commutative (see this question and my answer, and that the indexing operator []
binds more tightly than !
.
The lessons here are:
For any macro that's intended to be used as an expression, the entire macro definition should be enclosed in parentheses -- even if you can't think of a case where it would matter.
Keep It Simple. In C,
0
is the only false value, and1
is the canonical true value. (Any non-zero value is "true", but the built-in "Boolean" operators always yield0
or1
.) Using the!
operator to defineTRUE
in terms ofFALSE
(or vice versa) is just an unnecessary complication.
Use <stdbool.h>
if you can. If you can't (because you're stuck with a pre-C99 compiler), I recommend this:
typedef enum { false, true } bool;
It's not quite the same as C99's _Bool
/ bool
(conversions to this bool
type aren't normalized to 0
or 1
), but it's close enough for almost all purposes.