#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](
[To see links please register 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](
[To see links please register here]
) and [my answer](
[To see links please register here]
), and that the indexing operator `[]` binds more tightly than `!`.
The lessons here are:
1. 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.
2. Keep It Simple. In C, `0` is the only false value, and `1` is the canonical true value. (Any non-zero value is "true", but the built-in "Boolean" operators always yield `0` or `1`.) Using the `!` operator to define `TRUE` in terms of `FALSE` (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.