Re: TRUE vs true or FALSE vs false
On Wed, 16 Jun 2010 09:23:44 -0500, "JCO" <someone@somewhere.com> wrote:
What exactly is the difference. This has always bothered me that this is
the case. I've noticed that you cannot substitute one for the other. I'm
guessing TRUE was the original way of doing things before "true" came along?
The same case can be made with FALSE vs false.
Thanks to standard conversions, you almost always *can* substitute the
*constants* one for the other. That's less true for the *types*. To
understand the difference between the constants, start with the types.
The BOOL type is an ancient Windows typedef for int:
typedef int BOOL;
#define TRUE 1
#define FALSE 0
It's basically a code comment used to indicate boolean usage.[*] This was
about the best you could do in the C language of the time, and it's
consistent with the behavior of the relational operators, which yield ints
equal to 1 or 0. Note, however, that all non-zero values are considered
"true" in C and also when using BOOL, not just TRUE.
In contrast, the C++ bool type is a proper boolean type. The only values a
bool can hold are true and false. In expressions, true converts to 1 and
false to 0, which is why you can normally use true and false
interchangeably with TRUE and FALSE. Going the other way:
bool x = y; // y is non-bool
Assigning a non-bool value to a bool is equivalent to this:
bool x = y != 0;
The result of a relational operator is true or false in C++, so non-zero
values get converted to true, which is done to maintain the C notion that
non-zero means true. This is a big difference between bool and BOOL. If you
were to write:
BOOL x = 5;
Then x would contain the value 5 (still "true", but not TRUE). If you were
to write:
BOOL x = INT64_MAX;
Then x would contain 0 due to integer truncation. However, if you were to
change the type to bool, x would contain true in both cases.
Besides behavioral differences, there is a size difference to consider.
Obviously, sizeof(BOOL) == sizeof(int). However, sizeof(bool) is 1 in
Visual C++ and most other implementations, making it the same size as a
char.
I said earlier that the types are less interchangeable than the constants.
This is true simply because they are different types, which means you can't
pass the address of a bool where the address of a BOOL is required, using a
BOOL parameter to try to override a function that uses a bool parameter
won't work, and so forth.
So how to use all this? When there is a choice (see paragraph above for
cases for which there is not a choice, and also consider consistency when
writing things like Windows API wrappers), use bool instead of BOOL. It's
better behaved and smaller. As for the constants, it is very unlikely you
will run into a situation for which TRUE/FALSE vs. true/false matters, so
use whatever you want. I use true/false pretty much exclusively. If there
were to be a problem, it would be due to ambiguity resulting from something
like stupidly designed function overloads, and it wouldn't be a silent
error.
[*] Except for the GetMessage return value, which uses BOOL for three
states. Then there's the return value for CSingleLock::Lock, which IIRC
uses BOOL when there are three possible outcomes, except it just improperly
converts two of them into TRUE. There may be more BOOL abuse I'm not aware
of.
--
Doug Harrison
Visual C++ MVP