Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 647 Vote(s) - 3.61 Average
  • 1
  • 2
  • 3
  • 4
  • 5
#define TRUE !FALSE vs #define TRUE 1

#1
Putting aside the fact that since c99 the [`stdbool.h`][1] has existed, when defining macros to handle Boolean types in `C` is there any difference between the following?

#define FALSE 0

#define TRUE 1 // Option 1
#define TRUE !FALSE // Option 2

[From the live example here][2], it doesn't seem to make a difference. Is there a technical benefit to either option? (Not including the fact that the second example would work better with c++ `bool` objects.)


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#2
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.
Reply

#3
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*](

[To see links please register here]

) 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.
Reply

#4
Not much difference.

`#define TRUE 1` has a slight advantage over `#define TRUE !FALSE` in that `1` is a single item unaffected by operator precedence.

`!FALSE` could be `(!FALSE)` to cope with arcane code that attempts to use `++ -- [] . ->`, which have higher precedence next to `FALSE`.
Reply

#5
#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.
Reply

#6
They are just same.

- `!0` is `1` so `!FALSE` is `1`


`#define TRUE !FALSE` has no technical benefit at all although it existed for along time and appeared many where.

`#define TRUE !FALSE` can be misunderstood, one could think that `TRUE` represents every value which not `0`.

- Only `1` equals to `TRUE`, others values like `2`,`3`, `255`... (which `!=0`) does not equal to `TRUE`


**To prevent this misunderstanding**, many organizations require not using `#define TRUE !FALSE` any more or comparison to `TRUE` should be changed to `!FALSE`:

// Should not
if (var_bool == TRUE) {
...
}

//Should
if (var_bool != FALSE) {
...
}

Reply

#7
In the C language, TRUE is properly defined as (!FALSE) because while zero (0) is FALSE and FALSE is zero (0), *any other value* is TRUE. You can use almost any variable as a boolean expression, and if it is non-zero the value of the expression is TRUE. A NULL pointer is zero for just that reason. So is the end-of-string character ('\0'). There is a great deal of code written to take advantage of that fact. Consider:

while ( *d++ = *s++ );

The copy will end when the end-of-string character is copied. This idiom is very common. Never mind the buffer size issues.

This is one reason why it is a bad idea to test for equality to TRUE if you do not have a modern dedicated boolean type where the only possible values are TRUE and FALSE. I suggest you make it a habit to test for inequality to FALSE anyway, for safety's sake. You may not always get to work with the new and shiny.
Reply

#8
No much difference. But I think `#define TRUE 1` is better.

If you use `#define TRUE !FALSE`:

`FALSE` is 0 and `TRUE` is all numbers expect 0.

If you use `#define TRUE 1`:

`FALSE` is 0 and `TRUE` is 1. No problem.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through