Кажется, выравнивание - ваша проблема, посмотрите на pragma pack
. Имена struct / union просто ссылаются на выделенный блок памяти, если st_t.a сместится в структуру путем добавления большего числа членов, произойдет сбой приведения, но если он останется первым, он будет работать, поскольку все члены объединения указывают на тот же адрес, что и сам союз.
См. Раздел 9.2.17 - 21 C ++ - стандарт:
«Указатель на объект структуры стандартной компоновки, соответствующим образом преобразованный с использованием reinterpret_cast, указывает на его начальный элемент (или, если этот элемент является битовым полем, затем на модуль, в котором он находится), и наоборот.»
См. Также раздел 9.5 Союзы:
«1. В объединении в любое время может быть активен не более одного из элементов не статических данных, то есть значение не более одного из элементов не статических данных может быть сохранено в объединении в любое время. [Примечание: одна специальная гарантия сделана для упрощения использования объединений: если объединение стандартного макета содержит несколько структур стандартного макета, которые имеют общую начальную последовательность (9.2), и если объект этого типа объединения стандартного макета содержит одну из структур стандартного макета, разрешено проверять общую начальную последовательность любого из элементов структуры стандартного макета, см. 9.2. - примечание к концу] Размер объединения достаточен, чтобы содержать наибольшее из его нестатических члены данных. Каждый нестатический элемент данных выделяется так, как если бы он был единственным членом структуры. "