C++ Logo

sg12

Advanced search

Re: [ub] Type punning to avoid copying

From: Howard Hinnant <howard.hinnant_at_[hidden]>
Date: Fri, 26 Jul 2013 14:03:17 -0400
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

Received on 2013-07-26 20:03:14