Any reason for if(function() == TRUE) in C

Is there a good reason for doing if(SomeFunction() == true) instead of doing if(SomeFunction())

No.

If SomeFunction() returns a result of type _Bool, then the equality comparison should be reliable (assuming that the evaluation of the result did not involve undefined behavior). But the use of TRUE rather than true, and the type name BOOLEAN rather than _Bool or bool, suggest that the result is not an actual _Bool (available only in C99 or later), but some ad-hoc Boolean-like type -- perhaps an alias for int.

A value of any scalar type can be used as a condition in an if statement. If the value is equal to zero, the condition is false; otherwise, the condition is true. If TRUE is defined as 1, and SomeFunction() returns, say, 3, then the test will fail.

Writing

if (SomeFunction()) { /* ... */ }

is simpler, clearer, and more likely to behave correctly.

Note, for example, that the isdigit() et al functions declared in <ctype.h> do not just return 0 or 1; if the argument is a digit, isdigit() can (and does) return any non-zero value. Code that uses it is expected to handle it correctly -- by not comparing it for equality to 1, to true, or to TRUE.

Having said that, there might be a valid reason to compare something for equality to TRUE -- if it matters whether the result is equal to TRUE or has some other non-zero value. But in that case, using the names BOOLEAN and TRUE is misleading. The whole point of a Boolean type is that values are either true or false; there's no "maybe", and if there happen to be different representations of truth, you shouldn't care which one you have.

The guideline I try to follow is:

Never compare a logically Boolean value for equality or inequality to true or false (or 0, 1, FALSE, TRUE). Just test the value directly, with a ! operator if you want to invert the test. (A "logically Boolean" value either is of type _Bool, or is intended to distinguish between truth and falsehood with no additional information. The latter can be necessary if _Bool is not available.) Comparison to false can be safe, but there's no reason to do it; comparing the value directly is still clearer.

And if someone tells you that

if (SomeFunction() == true)

is better than

if (SomeFunction())

just ask them why

if ((SomeFunction() == true) == true)

isn't even better.

See also section 9 of the comp.lang.c FAQ. Its emphasis on pre-C99 solutions is perhaps a bit dated, but it's still valid.

UPDATE: The question asks about a function that returns the value TRUE of type BOOLEAN, defined something like this:

typedef enum { FALSE, TRUE } BOOLEAN;

Such definitions were useful in pre-1999 C, but C99 added the predefined Boolean type _Bool and the header <stdbool.h>, which defines macros bool, false, and true. My current advice: Use <stdbool.h> unless there's a serious concern that your code might need to be used with an implementation that doesn't support it. If that's a concern, you can use

typedef enum { false, true } bool;

or

typedef int bool;
#define false 0
#define true 1

(I prefer the first.) This isn't 100% compatible with the C99 definitions, but it will work correctly if you use it sensibly.


Since in C any non-zero value is considered true and only zero false you should never compare to one specific TRUE macro definition in any event. It is unnecessarily specific. The form:

if( fn() )

is the simplest form, but if you do prefer to compare to a specific value, then only compare to FALSE thus:

if( fn() != FALSE )  // Safer than '== TRUE', but entirely unnecessary

which will work for all reasonable definitions of FALSE and also if fn() is not BOOLEAN. But it remains totally unnecessary.

Personally for easier debugging I'd prefer:

 BOOLEAN x = fn() ;
 if( x )

As well as being able to observe the return value in your debugger before entering or skipping the conditional block, you have the opportunity to name x something self documenting and specific to the context, which the function name might not reflect. In maintenance you are more likely to maintain a variable name than correct a comment (or many comments). In addition x is then available to use elsewhere rather then calling fn() multiple times (which if it has side effects or state may not return the same value).

Another problem with user defined boolean types and values is that the definitions may not be consistent throughout - especially if you use third-party code whose authors also thought it a good idea to define their own using the same symbol names as yours. If the names differ (such as BOOL, BOOLEAN or OS_BOOL for example), when your code interfaces to this third-party code, you then have to decide whose boolean type should be used in any particular circumstance, and the names of TRUE and FALSE are likely to clash with redefinition warnings or errors.

A better approach would be to update the code to use stdbool.h and the real boolean type bool (an alias for the built in _Bool in C99) which can have only two values true and false. This will still not protect you from the case where fn() is not a bool function and returns an integer other then zero or one, but there is then the chance that the compiler will issue a type mismatch warning. One of the best things you can do to refactor legacy code in and case is to set the warning level high and investigate and fix all the warnings (and not just by liberal casting!).