C ISO-standardis TRUE == ~FALSE? - Stack Overflow

admin2025-04-25  2

I saw C code whch defined:

#define TRUE (~FALSE)

It's from a guy who has a higher grade than me, and his degree program contained much more about C.

Nevertheless, I assume, this is not ISO C conforming, because this is -1. I found <stdbool.h>, where only the lowercase true and false are defined.

I would like to have a reliable source or link to the specification of TRUE.

I saw C code whch defined:

#define TRUE (~FALSE)

It's from a guy who has a higher grade than me, and his degree program contained much more about C.

Nevertheless, I assume, this is not ISO C conforming, because this is -1. I found <stdbool.h>, where only the lowercase true and false are defined.

I would like to have a reliable source or link to the specification of TRUE.

Share Improve this question edited Jan 16 at 12:47 Eric Postpischil 227k14 gold badges192 silver badges366 bronze badges asked Jan 16 at 12:24 rundekugelrundekugel 1,4711 gold badge14 silver badges23 bronze badges 6
  • 5 TRUE and FALSE are not specified by the C standard. It has true and false, which are different. – Eric Postpischil Commented Jan 16 at 12:29
  • 7 Before C99 there was no standard way to use bool, true, false, etc. People only had int and the standard way was that 0 meant false, and any other value meant true. Assuming a previous definition of #define FALSE 0, the shown definition of #define TRUE (~FALSE) was (and still is nowadays) perfectly acceptable. – pmg Commented Jan 16 at 12:30
  • 3 This is the reason you should always do if(condition) instead of if(condition == true) in legacy codebases (or in new ones also). You never know what value true has been defined with. – user694733 Commented Jan 16 at 12:36
  • 3 @pmg No, #define TRUE (~FALSE) was never acceptable, it's utter nonsense. Consider something like BOOL upper_case = TRUE; ... if(upper_case == isupper(ch)). As in, logical/relational etc operators in C return 0 and 1 and they absolutely do need to be compatible with the (would-be) boolean type. – Lundin Commented Jan 16 at 14:23
  • 3 A common pre-C99 definition was typedef enum { FALSE, TRUE } BOOL; – Lundin Commented Jan 16 at 14:24
 |  Show 1 more comment

3 Answers 3

Reset to default 8

FALSE and TRUE are not specified by the C standard. There is no specific source for this except that searching the entire C standard for “FALSE” and “TRUE” shows these character strings are not present as words in the standard.

In versions of the C standard from 1999 to 2018, false and true were specified to be macros defined by <stdbool.h> as integer constants 0 and 1. In C 2024, they are keywords for constants of type bool with values 0 and 1.

FALSE and TRUE may be used by C programs for their own purposes. Presumably FALSE is defined as 0 or something similar, although you do not show it. This results as TRUE having the value −1 in most C implementations. The C standard does not prohibit that, and it will serve as a “true” condition in various tests, such as if (x) …. However, the value −1 may be surprising to some programmers, and that could cause some problems if their code is not written with some flexibility about this in mind. For example, this code:

int a = 3;
int b = 3;
int ExpectedTestResult = TRUE;
if ((a == b) == ExpectedTestResult)
    printf("No problem found.\n");
else
    printf("Problem found.\n");

will incorrectly report “Problem found” because, while attempting to determine whether a == b reports the result in ExpectedTestResult, it gets 1 for a == b, but ExpectedTestResult is −1.

In esoteric C implementations, ~FALSE could have a value of −0 (when using one’s complement) or a large negative value (when using sign-and-magnitude). The former would cause TRUE to evaluate as a “false” condition. However, such C implementations are effectively non-existent in modern practice.

Generally, it could be better to define TRUE as (!FALSE).

The presented code is conforming.

TRUE is not a reserved name, you can #define it however you want, and C specification does not limit how users define not-reserved symbols. If you want #define TRUE anything or #define TRUE false you can do whatever you want.

It's conforming in the sense that TRUE and FALSE are not reserved words, (~FALSE) is a valid expression, it uses #define correctly, etc.

Buuuut...

Expressions involving logical or relational operators (a == b, a > b, etc.) will evaluate to 0 or 1; similarly, the isxxx library functions (isdigit, isnan, etc.) return 0 or 1. Assuming FALSE is defined as 0, ~FALSE evaluates to -1 (or 0xFFFFFFFF...), so something like

if ( isdigit( c ) == TRUE )

will always fail.

A better option would be to define TRUE as

#define TRUE (!FALSE)

which will define TRUE as 1.

An even better option would be to #include <stdbool.h> and use the predefined true and false constants.

The best option is to avoid using Boolean constants where feasible; i.e., instead of writing

if ( isdigit( c ) == true )

just write

if ( isdigit( c ) )

Many years ago, before the introduction of stdbool.h, it was fairly common practice for everyone to define their own TRUE and FALSE constants. On one project, someone (not me!) dropped a header that meant to define TRUE as !FALSE, but screwed up and wrote

#define TRUE FALSE // oops

I spent half the day chasing my tail trying to figure out why my code was blowing up left and right. Not coincidentally, that was the day I stopped using Boolean constants in my code.

转载请注明原文地址:http://anycun.com/QandA/1745532157a90852.html