Да, это возможно и полезно.Причина та же самая причина X в Y полезна для многих значений X и Y: композиционность.Программы создаются путем объединения крошечных компонентов в маленькие компоненты в более крупные компоненты в огромные компоненты в ... Иногда случается, что кучка союзов собирается в объединение, и что с того?
R .. 'Ответ s показывает пример, где это происходит за кулисами: просто случается, что один из типов членов объединения является объединением, но вы не узнаете об этом, если не посмотрите на реализацию библиотеки.
EDIT Однако обратите внимание, что общая идиома для дискриминируемых объединений, где каждый член объединения является структурой, первое поле которой является целочисленным типом, содержащим тег, не распространяется на вложенные объединения.Таким образом, ниже приводится стандартная ( N1256 §6.5.2.3.5) реализация дискриминационных объединений в C:
struct generic {
unsigned tag;
};
struct smallnum {
unsigned tag; /*always TAG_SMALLNUM*/
unsigned value;
};
struct bignum {
unsigned tag; /*always TAG_BIGNUM*/
size_t length;
unsigned *p;
};
struct string {
unsigned tag; /*always TAG_STRING*/
size_t length;
char *p;
};
union number {
struct bignum bignum;
struct smallnum smallnum;
};
union object {
struct generic generic;
struct bignum bignum;
struct smallnum smallnum;
struct string string;
};
Если у вас есть union object
объект x
, вы всегда можете прочитать его тег как x.generic.tag
(или x.bignum.tag
или любой другой), независимо от того, что на самом деле было присвоено объекту.Используя уникальные теги (дискриминаторы) для объектов.
Следующее определение является допустимым, но бесполезным, так как вы не можете просто прочитать первое поле объекта union level2
, чтобы получить тег: if union level2
объект был записан как union number
, вы должны прочитать его тег через член number
, в противном случае вы должны прочитать его тег через член generic
или string
.Я не удивлюсь, если доступ через неправильный член сработает в каждой существующей реализации, но он не соответствует стандартам.
union level2 {
struct generic generic;
union number number;
struct string string;
};