C++ 11 говорит (9.2):
Если стандартный макет-объединение которых содержит два или более стандартной компоновку структур, которые имеют общую исходную последовательность, и если стандартный макет объект в данный момент накидного содержит одну из этих структур стандартной компоновки, разрешено для проверки общей исходной части любого из них. Две структуры стандартного компоновки имеют общую начальную последовательность , если соответствующие члены имеют совместимые с макета типы, и ни один из них не является битовым полем или оба являются битовыми полями с одинаковой шириной для последовательности из одного или нескольких начальных элементов ,
Что касается того, массивов разного размера образуют действительную общую начальную последовательность, 3.9 говорит:
Если два типа Т1 и Т2 имеют одинаковый тип, то T1 и T2 макет-совместимые типы
Эти массивы не идентичны, поэтому это не относится. Дополнительного исключения для массивов не существует, поэтому массивы не могут быть совместимы с макетами и не образуют общую начальную последовательность.
На практике, однако, я не знаю компилятор (GCC), который:
- игнорирует «общая начальная последовательность» правила, и
- позволяет ввести каламбуров в любом случае, но только тогда, когда доступы «с помощью тип объединения "(как в вашем примере), и в этом случае правило« обычной исходной последовательности »выполняется косвенно (поскольку« общая начальная последовательность »подразумевает общий начальный макет на архитектурах, поддерживаемых компилятором).
Я подозреваю, что многие другие компиляторы используют аналогичный подход. В вашем примере, где вы вводите pun-union через объект union, такие компиляторы выдадут вам ожидаемый результат - чтение из неактивного элемента должно дать вам значение, написанное через неактивный элемент.
Без всяких аргументов я считаю, что это законно. – knivil