строгие псевдонимы и выравнивание

Мне нужен безопасный способ алиаса между произвольными типами POD, соответствующий ISO-C++11, с явным учетом 3.10/10 и 3.11 n3242 или более поздней версии. Здесь много вопросов о строгом алиасинге, большинство из них касается C, а не C++. Я нашел «решение» для C, которое использует объединения, вероятно, используя тип объединения этого раздела

, который включает один из вышеупомянутых типов среди его элементы или нестатические данные-члены

Из этого я построил это.

#include <iostream>

template <typename T, typename U>
T& access_as(U* p)
{
    union dummy_union
    {
        U dummy;
        T destination;
    };

    dummy_union* u = (dummy_union*)p;

    return u->destination;
}

struct test
{
    short s;
    int i;
};

int main()
{
    int buf[2];

    static_assert(sizeof(buf) >= sizeof(double), "");
    static_assert(sizeof(buf) >= sizeof(test), "");

    access_as<double>(buf) = 42.1337;
    std::cout << access_as<double>(buf) << '\n';

    access_as<test>(buf).s = 42;
    access_as<test>(buf).i = 1234;

    std::cout << access_as<test>(buf).s << '\n';
    std::cout << access_as<test>(buf).i << '\n';
}

У меня вопрос, просто чтобы убедиться, является ли эта программа законной в соответствии со стандартом? *

Он не выдает никаких предупреждений и отлично работает при компиляции с MinGW/GCC 4.6.2 с использованием:

g++ -std=c++0x -Wall -Wextra -O3 -fstrict-aliasing -o alias.exe alias.cpp

*Редактировать: И если нет, как можно изменить это, чтобы оно было законным ?

19
задан timrau 27 August 2012 в 14:09
поделиться