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
.
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.
TRUE
andFALSE
are not specified by the C standard. It hastrue
andfalse
, which are different. – Eric Postpischil Commented Jan 16 at 12:29bool
,true
,false
, etc. People only hadint
and the standard way was that0
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:30if(condition)
instead ofif(condition == true)
in legacy codebases (or in new ones also). You never know what valuetrue
has been defined with. – user694733 Commented Jan 16 at 12:36#define TRUE (~FALSE)
was never acceptable, it's utter nonsense. Consider something likeBOOL upper_case = TRUE; ... if(upper_case == isupper(ch))
. As in, logical/relational etc operators in C return0
and1
and they absolutely do need to be compatible with the (would-be) boolean type. – Lundin Commented Jan 16 at 14:23typedef enum { FALSE, TRUE } BOOL;
– Lundin Commented Jan 16 at 14:24