Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 questions too, because in my honest opinion, in embedded systems (which might be 8bit systems) this might be a real problem (or not).

  3. New question: Is this really undefined behavior? If yes, why? If not, why? Aren't there any assumptions on the boolean comparison operators in the specs?

like image 801
SztupY Avatar asked Aug 09 '09 20:08

SztupY


1 Answers

If you read a member of a union that is a different member than the last member which was written then you get undefined behaviour. Writing an int member and then reading the union's bool member could cause anything to happen at any subsequent point in the program.

The only exception is where the unions is a union of structs and all the structs contain a common initial sequence, in which case the common sequence may be read.

like image 179
CB Bailey Avatar answered Nov 15 '22 19:11

CB Bailey