-1

I would expect the following code to produce equality, but bool values are shown to be different.

#include <iostream>

union crazyBool
{
    unsigned char uc;
    bool b;
};

int main()
{
    crazyBool a, b;
    a.uc = 1;
    b.uc = 5;

    if(a.b == b.b)
    {
            std::cout << "==" << std::endl;
    }
    else
    {
            std::cout << "!=" << std::endl;
    }

    bool x, y;
    void *xVP = &x, *yVP = &y;
    unsigned char *xP = static_cast<unsigned char*>(xVP);
    unsigned char *yP = static_cast<unsigned char*>(yVP);

    (*xP) = (unsigned char)1;
    (*yP) = (unsigned char)5;

    if(x == y)
    {
            std::cout << "==" << std::endl;
    }
    else
    {
            std::cout << "!=" << std::endl;
    }
    return 0;
}

Note that here we are not only changing the value through union (which was pointed out as being undefined), but also accessing memory directly via void pointer.

v010dya
  • 5,296
  • 7
  • 28
  • 48
  • 6
    *"I would expect"* - and that's where you went wrong - what you've done has *undefined behaviour*, which should be so expected I'm not going to bother quoting the Standard to prove it to you. – Tony Delroy May 11 '15 at 05:49
  • 1
    You have to initialize `a.b` and `b.b`. Not sure how this leads you to your "bitwise" conclusion, whatever that means. – juanchopanza May 11 '15 at 05:50
  • @TonyD Does it deal with that at all in the standards? – v010dya May 11 '15 at 05:51
  • 1
    @Volodya: most certainly - there's a very precise description of how you're allowed to set and then read fields in unions. – Tony Delroy May 11 '15 at 05:52
  • 1
    [Somewhat related](http://programmers.stackexchange.com/questions/198284/why-is-0-false) – Levi May 11 '15 at 05:53
  • Ignoring trolling i have edited the question, now it is *not* about unions any longer. – v010dya May 11 '15 at 06:25
  • 2
    @Volodya Answer to your edit: bool operations are not required to handle every possible `unsiged char` value, and `unsigned char` can have a different size, so your code is even more undefined now. And no one is trolling, except maybe for you because you´re changing the question completely after closing. – deviantfan May 11 '15 at 06:55
  • @deviantfan 1) The question was never about unions. 2) "please edit this question to explain how it is different" This is what it says under the question. 3) Neither is the question about unsigned char, but if you want i can add a test that unsigned char on my platform takes 8 bits. – v010dya May 11 '15 at 07:01
  • 1
    1) No? Then what was it? 2) Did you explain how your original question was different compared to the duplicate? No, you did change your original question. 3) Yes it is, see your code. And "your platform" is not "every supported platform". That standard is for latter. And even if the size is equal, the operation problem is still there. It´s the same as writing `float`´s to your `bool`´s memory and comparing them by bool comparison => It´s nonsense. – deviantfan May 11 '15 at 07:03

1 Answers1

3

If you assign to a member of a union, that member becomes the active member.

Reading any member other than the active one is undefined behavior, meaning that anything could happen. There are a few specific exceptions to this rule, depending on the version of the C++ standard your compiler is following; but none of these exceptions apply in your case.

(One of the exceptions is that if the union has multiple members of class type where the classes have the same initial members, these shared members can be read through any of the union's members.)

Edit to address the question clarification:

The standard defines bool as having the values true and false, no others. (C++11, 3.9.1/6) It never defines what it means to copy some other bit pattern over the storage (which is what you are doing). Since it doesn't define it, the behavior is undefined too.

Yes, when converting an integer to a bool 0 becomes false and anything else becomes true, but that is just a conversion rule, not a statement about bool's representation.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
  • The point isn't about Unions, perhaps i should have removed them from the code all together, since perhaps i was using them in the way they weren't designed to be used. I was attempting to write directly into the memory space of bool, in order to control for conversion at initialisation. – v010dya Jul 27 '15 at 09:52