1

what really means by type-punning in the union? for example

#include <iostream>

using namespace std;

union test {
    int x;
    float y;
};

int main()
{
    test t;
    t.y = 1.5;
    cout<<t.x;

    return 0;
}

gives output as 1069547520

what does this value represent? how to predict this?

timrau
  • 22,578
  • 4
  • 51
  • 64
Shard
  • 13
  • 2

1 Answers1

2

Type-puning means reinterpreting the underlying bytes of one type as bytes of another. Unions can be (mis)used for this because all members share the same memory location.

Reading from non-active union member is undefined behaviour in C++. It is allowed in C and GNU C++.

The correct C++ approach for trivially copyable types is to use std::memcpy:

#include <cstring>

int main()
{
    std::uint32_t x = 12;
    
    float y;
    // This is OK, but the value of `y` is implementation-defined.
    std::memcpy(&y,&x,sizeof(x));
    // THIS IS UNDEFINED BEHAVIOUR.
    y = *reinterpret_cast<float*>(&x);

    static_assert(sizeof(x)==sizeof(y),"Sanity check");
}

Note that reinterpret_cast<T*>(address) is not enough because it requires T object to exist at address otherwise you are breaking the strict aliasing rule (with some exceptions). There is also no need to worry about performance degradation of using std::memcpy, with optimizations no bytes will be copied unless needed. The call will just serve as a hint to the compiler that you really meant to do that.

Although, the example above does not exhibit undefined behaviour, the value of y still depends on precise bit representation of integers and floats which are mostly implementation-defined. In C++20 the integers are required to use 2-complement but floats are not required to adhere to e.g. IEEE 754.

Quimby
  • 17,735
  • 4
  • 35
  • 55
  • 1
    They could also use the new `std::bit_cast` if they can use C++20. – NathanOliver Jul 30 '21 at 20:09
  • 1
    can you please tell me about the output of the above example? like what does that represent? why is it the same every time with any machine? can we predict that output on paper without using any programming language? – Shard Jul 30 '21 at 20:10
  • 2
    @Shard The output won't always be the same on any machine. The encoding for `float` is not specified, so implementations could be using different kinds of `float` which will produce different results. – François Andrieux Jul 30 '21 at 20:12
  • @Shard Added an extra paragraph. Yes, if you know which representation the compiler uses for numbers you can use pen&paper, see e.g. [IEE 754 wiki](https://en.wikipedia.org/wiki/IEEE_754-1985) for the most likely `float` format present on your machine. "Implementation-defined" means the code is safe but the program's output depends on the particular compiler and computer's architecture. The behaviour must be specified somewhere in the compiler's docs. – Quimby Jul 30 '21 at 20:17
  • @Quimby: Note also that the Standard explicitly specifies that actions which it characterizes as "Undefined Behavior" may be "processed in a documented manner characteristic of the environment". The Standard makes no attempt to identify all of the useful tasks for which the language might be employed, and is agnostic to situations where processing code in such a documented manner might facilitate the performance of some such tasks by non-portable programs. – supercat Oct 20 '22 at 18:28