Синтаксические проблемы
Назначенные инициализаторы в совокупной инициализации формально являются частью C ++ 20 стандарта .
Однако они имеют серьезные ограничения по сравнению с C99:
- Они должны появляться в том же порядке, что и декларация;
- Все обозначенные элементы должны быть прямымичлены совокупности;
- Вложение возможно, только если вложенный инициализатор
В вашем случае скомпилируется следующее, но это не даст ожидаемых преимуществ от гибкости, которые вы ожидаете отявное имя:
Word_t w2 = (Word_t) {._word16Bits { .leastSignificant16Bits = 0xABCD, .mostSignificant16Bits = 0x1234} };
Более серьезные проблемы
Во-первых, этот код, если он будет работать, не является переносимым: он предполагает немного порядка байтов целевой архитектуры,
Во-вторых, и это очень важно, C ++ имеет строгие ограничения на профсоюзы. Это необходимо с точки зрения согласованности жизненного цикла объекта. В частности:
[class.union] / 1 : В объединении в любой момент может быть активен не более одного не статического члена данных, то естьзначение не более одного из нестатических элементов данных может быть сохранено в объединении в любое время.
Таким образом, если вы создаете объединение с одним активным членом (тот, который используется в вашем инициализаторе)другой участник не активен, и вы не должны получать к нему доступ. Предусмотренное единственное исключение не применимо к вашему случаю:
[Примечание. Для упрощения использования объединений предоставляется одна специальная гарантия: если объединение стандартных макетов содержит несколько структур стандартных макетов, которыесовместно использовать общую начальную последовательность, и если объект этого типа объединения стандартной компоновки содержит одну из структур стандартной компоновки, разрешается проверять общую начальную последовательность любого из элементов структуры стандартной компоновки;- конец примечания]
Стандарт также дает подсказки о способе изменения активного члена объединения:
[Примечание: В общем случае необходимо использовать явный деструкторзвонки и размещение новых операторов для смены активного члена профсоюза. - конец примечания]
Это, как говорится, для простых скалярных типов, может компилироваться и работать, как вы ожидаете, на большинстве основных компиляторов.
Но дело в том, что использование вами профсоюзов несовместимо со стандартом . Это UB, и даже если он работает на некоторых реализациях сейчас, при каждом новом выпуске компилятора у вас не будет гарантии, что он продолжит работать, подвергая риску все свои инвестиции.
Почему пришло времяизменить подход?
C99 имеет меньше ограничений на союзы, как C ++. Но это также не дает твердой гарантии относительно значения, которое может быть прочитано в одном члене объединения, когда был задан другой член объединения:
6.2.6.1 / 7 : Когда значениехранящиеся в элементе объекта типа объединения, байты представления объекта, которые не соответствуют этому элементу, но соответствуют другим элементам, принимают неопределенные значения.
Это упоминается в приложении C99 /J что такое использование союзов - неопределенное поведение, которое может создать проблемы переносимости.