Type punning cast with patterns

I would like to know if the following code is an acceptable method for handling punning so that it does not violate strict alias rules. I understand that this method is based on the extension of the GCC compiler, so there is no need to point this out.

template <class output_type, class input_type>
inline output_type punning_cast(const input_type& input)
{
    static_assert(std::is_pod<output_type>::value, "output_type for punning_cast must be POD");
    static_assert(std::is_pod<input_type>::value, "input_type for punning_cast must be POD");
    static_assert(sizeof(output_type) == sizeof(input_type), "input_type and output_type must be the same size");

    typedef output_type __attribute__((may_alias)) output_type_may_alias;

    return *reinterpret_cast<const output_type_may_alias*>(&input);
}

template <class output_type, class input_type>
inline output_type punning_cast(const input_type* input)
{
    static_assert(std::is_pod<output_type>::value, "output_type for punning_cast must be POD");
    static_assert(std::is_pod<input_type>::value, "input_type for punning_cast must be POD");

    typedef output_type __attribute__((may_alias)) output_type_may_alias;

    return *reinterpret_cast<const output_type_may_alias*>(input);
}

Usage example:

uint32_t float_as_int = punning_cast<uint32_t>(3.14f);

unsigned char data[4] = { 0xEF, 0xBE, 0xAD, 0xDE };
uint32_t magic = punning_cast<uint32_t>(data);
+4
source share
1 answer

I use the union for this. Sort of:

template <class output_type, class input_type>
inline output_type punning_cast(const input_type& input)
{
    union {
        input_type in;
        output_type out;
    } u;

    u.in = input;
    return u.out;
}

, Undefined ++ ( C). , ++, " , " ... , .

, , memcpy, , , , "" . , .

, union .

[]

GCC :

, ( "-" ) . -fstrict-aliasing, , .

, GCC, , union.

+5

Source: https://habr.com/ru/post/1539997/


All Articles