Alex Rivera | Logout

Strange C++ boolean casting behaviour (true!=true)

Asked 2009-08-09T20:06:20.743
11

Just read on an internal university thread:

#include <iostream>
using namespace std;

union zt
{
 bool b;
 int i;
};

int main()
{
 zt w;
 bool a,b;
 a=1;
 b=2;
 cerr<<(bool)2<<static_cast<bool>(2)<<endl;                      //11
  cerr<<a<<b<<(a==b)<<endl;                                      //111
 w.i=2;
 int q=w.b;
 cerr<<(bool)q<<q<<w.b<<((bool)((int)w.b))<<w.i<<(w.b==a)<<endl; //122220
 cerr<<((w.b==a)?'T':'F')<<endl;                                 //F
}

So a,b and w.b are all declared as bool. a is assigned 1, b is assigned 2, and the internal representation of w.b is changed to 2 (using a union).

This way all of a,b and w.b will be true, but a and w.b won't be equal, so this might mean that the universe is broken (true!=true)

I know this problem is more theoretical than practical (a sake programmer doesn't want to change the internal representation of a bool), but here are the questions:

  1. Is this okay? (this was tested with g++ 4.3.3) I mean, should the compiler be aware that during boolean comparison any non-zero value might mean true?
  2. Do you know any case where this corner case might become a real issue? (For example while loading binary data from a stream)

EDIT:

Three things:

  1. bool and int have different sizes, that's okay. But what if I use char instead of int. Or when sizeof(bool)==sizeof(int)?

  2. Please give answer to the two questions I asked if possible. I'm actually interested in answers to the second

Edit
Report

1 Answer

9

Normally, when assigning an arbitrary value to a bool the compiler will convert it for you:

int x = 5;
bool z = x; // automatic conversion here

The equivalent code generated by the compiler will look more like:

bool z = (x != 0) ? true : false;

However, the compiler will only do this conversion once. It would be unreasonable for it to assume that any nonzero bit pattern in a bool variable is equivalent to true, especially for doing logical operations like and. The resulting assembly code would be unwieldy.

Suffice to say that if you're using union data structures, you know what you're doing and you have the ability to confuse the compiler.

answered 2009-08-09T20:12:12.777

Your Answer