Antho A
Antho A

Reputation: 78

C++ Assign a NAN value to a float inside a union

I have a strange behavior I'd like to understand. I have the following code:

    union floatInt
    { 
        float f;
        unsigned int l;
    };

    floatInt A, B;

    A.l = 0xFFA70B56;
    B.f = A.f;

    std::cout << std::hex << B.l << std::endl;

This works fine except in 1 configuration: Linux in non-debug mode, then I have this result: ffe70b56

And I don't really understand why the value has changed. I've been through several points to understand this:

  1. cppreference/union specifies that

    It's undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.

    But what would be the purpose of a union if we cannot use the other members? Moreover, it points to the same memory location, so it shouldn't be different.

  2. The value I'm using (0xFFA70B56) is NAN in IEEE 754 standard. So, when it is affected to another variable, can it be interpreted and changed to another NAN value like 0xFFE70B56?
  3. If I declare B as volatile, then the error disappears. Note that the variable isn't used anywhere else in the code. So has it something to do with compiler optimization?

Upvotes: 2

Views: 429

Answers (2)

granmirupa
granmirupa

Reputation: 2790

But what would be the purpose of a union if we cannot use the other members?

The purpose of union is to save memory by using the same memory region for storing different objects at different times.

The memory occupied by your floatInt is the same of the memory occupied by a float variable. In case your goal is to use a union, I suggest to add a boolean element that keep track of which of the two elements is used.

If you want to use both attributes you should use struct or (we are in c++) class

For more about union read here

Upvotes: 1

Mark Ransom
Mark Ransom

Reputation: 308462

Your NaN is being converted from a signalling NaN to a quiet NaN. The upper bit of the fraction, bit 22, changes from a zero to a one.

You might see the same behavior even if you weren't using a union.

Upvotes: 0

Related Questions