[ub] Type punning to avoid copying

Howard Hinnant howard.hinnant at gmail.com
Fri Jul 26 20:03:17 CEST 2013


I am attempting to correctly use a union:

#include <new>
#include <type_traits>

template <class X, class Y>
class V
{
    static_assert(std::is_trivial<X>(), "X must be a trivial type");
    static_assert(std::is_trivial<Y>(), "Y must be a trivial type");

    union
    {
        X x_;
        Y y_;
    };

    unsigned active_ = 0;

public:

    X& first()
    {
        if (active_ == 1)
        {
            y_.~Y();
            ::new (&x_) X;
            active_ = 0;
        }
        return x_;
    }

    Y& second()
    {
        if (active_ == 0)
        {
            x_.~X();
            ::new (&y_) Y;
            active_ = 1;
        }
        return y_;
    }
};

float InverseSquareRoot6(float x)
{
    V<float, int> u;
    u.first() = x;    
    float xhalf = 0.5f*x;
    u.second() = 0x5f3759df - (u.second()>>1);
    u.first() = u.first()*(1.5f - xhalf*u.first()*u.first());
    return u.first();
}

Both members of the union in V are constrained to be trivial types.  I keep track of which member of the union is active at all times.  I only allow read/write access to the active member of the union.  I switch which member of the union is active following the guidance of [class.union]/p4.

Does anyone see any rule that has been broken?

Thanks,
Howard



More information about the ub mailing list