danatel
danatel

Reputation: 4982

Can two booleans be compared in C++?

Is the following piece of code supposed to work?

bool b1 = true;
bool b2 = 1 < 2;
if (b1 == b2)
{
// do something
}

I suspect that not all 'trues' are equal.

Upvotes: 8

Views: 31218

Answers (8)

Darrell
Darrell

Reputation: 33

I've been reading all of these answers about why true is true and why two boolean variables can be compared using == or != except in rare cases where an integer is coerced to be a bool or some such thing. However, I'm having exactly the same problem as the original poster. I have two boolean variables, each of which is 'true', but when I compare them, I find that they are not equal. Here is the line of code,

if (angDegDiff > 15 || scaleRatioA > 5 || scaleRatioB < -5 || (isParallel2 != isParallel1)) { return false; }

In my example, angDegDiff = 0, scaleRatioA = 0, scaleRatioB = 0, isParallel2 = true, and isParallel1 = true. Still, the statement evaluates to true and the only way for that to happen is if isParallel2 is not equal to isParallel1.

No fancy methods are being used to set the values of isParallel1 or isParallel2. Their values are set by a statement such as _isParallel = true;. Later, that value is copied to another variable using a statement such as isParallel1 = geom1->IsParallel(); which is implemented as return _isParallel;.

My conclusion is that, depending upon the compiler, two boolean variables cannot be reliably compared for equality. I'm using Microsoft Visual C++ 2005, Version 8.0.50727.4039.

Epilogue: I replaced the boolean comparison in my code with the expression, ((isParallel1 && !isParallel2) || (!isParallel1 && isParallel2)) and now everything works fine.

Upvotes: 0

Steve Fallows
Steve Fallows

Reputation: 6424

Yes, as others have said bools can be compared for equality in C++. You may be thinking of things you heard from C. Since C has no bool type, booleans are represented as integers. In a boolean context any non-zero integer is true. However, they might have different bit patterns and thus not be equal. So the rule in C was not to compare 'booleans'.

Edit: per comments, C99 has a bool type. However the point of the answer was to indicate why the idea of not comparing bools is floating around. It is based on the long history of C, prior to C99.

Upvotes: 8

AnT stands with Russia
AnT stands with Russia

Reputation: 320471

When you assign an integral value to a boolean object (or initialize boolean object with an integral value) it is implicitly converted to a true or false by a standard boolean conversion (4.12). So, from the language point of view, your 1 and 2 are gone without a trace long before you even do the comparison. They both have become the very same true. There's no "all trues are equal" issue here. There's only one true.

Of course, some compiler might probably take a "lazy" approach and keep multiple different "trues" around, making sure that they "all are equal" at the moment of comparison and such, but I doubt this is a reasonable/viable approach.

In other words, in a reasonable implementation you should expect not only your comparison to hold true, but a much stronger comparison to be true as well:

bool b1 = true; 
bool b2 = 1 < 2;
if (memcmp(&b1, &b2, sizeof(bool)) == 0) {
  /* We should get in here */
}

This is not guaranteed by the language, but in real life it does describe the physical side of the situation quite well.

Upvotes: 2

SF.
SF.

Reputation: 14049

The problems are only when you get used to non-zero being true and forget that not all non-zeros are equal.

Imagine this:

You have a function keyPressed() that returns 0 on no key pressed, number of key when a key is pressed.

You wrote a simple switch in a loop:

if(keyPressed() && allow)
...

Now your company introduces normally open triggers in the devices and you need a pref.

bool key_switches_on = getPref("KeySwitchesOn");

if((keyPressed() && allow) == key_switches_on)
...

Then you notice "allow" is placed wrong...

if((keyPressed() == key_switches_on) && allow)

and suddenly only key number 1 works.

Upvotes: 0

David Thornley
David Thornley

Reputation: 57036

In C++, bool is its own type, with the two possible values true and false. All comparisons will go as you expect. All true boolean values are the same thing, and the same with all false. It is true that not all expressions you can evaluate to true or false are the same.

In C89, to go back as far as I want to, any zero value (of any pointer or numeric type) is false, and anything else is true. This means that true values aren't necessarily equal to each other. 1 and 2 are true values, but 1 != 2, and 1 & 2 evaluates to 0, which is false.

It's also possible for C89 false values to not compare equal, although they will on every implementation I've ever used. A null pointer value is a constant integral zero cast to a pointer value. It is possible for a non-constant value 0 cast to a pointer value to not be a null pointer (and there have been systems where null pointers were not all bits 0). Therefore, (void *)0 is a null pointer value, and hence false, but int i;...i = 0;...(void *)i could possibly not be a null pointer value, and hence not false.

However, in C89, all operations that intend to return a boolean value (like && or ==, for example), will return 1 or 0, so that (1 == 3) == (4 ==3).

Upvotes: 2

J. Calleja
J. Calleja

Reputation: 4905

Yes, boolean values can only store true or false, and you can compare the values for equality.

However, some bad uses of bool variables can lead to "undefined" behaviours and might look as if it is neither true nor false. For example reading the value of an uninitialized automatic variable or direct memory copy from integers.

Take a look at the following (bad) example:

  bool b1 = true; 
  bool b2 = true; 
  *((char*)&b1) = 3;

  if( b1 ) cout << "b1 is true" << endl;
  if( b2 ) cout << "b2 is true" << endl;
  if (b1 != b2) cout << "b2 is not equal to b1" << endl;

On Visual Studio 9, it shows:

b1 is true

b2 is true

b2 is not equal to b1

Probably, because the compiler has directly compare the values stored.

Upvotes: 11

T.E.D.
T.E.D.

Reputation: 44804

In C with ints you might have a point (although even there I think this particular sequence would be OK). In C++, yes this is safe.

Upvotes: 1

Daniel Daranas
Daniel Daranas

Reputation: 22624

Yes. All trues are equal.

Upvotes: 21

Related Questions