Краткий ответ: нет другого способа, кроме как добавить enum где-нибудь в вашей структуре вне объединения.
enum TestUnionPart
{
TUP_STRUCT,
TUP_TOTAL
};
struct TestUnionStruct
{
enum TestUnionPart Part;
union
{
struct
{
unsigned int Num;
unsigned char Name[5];
} TestStruct;
unsigned char Total[7];
} TestUnion;
};
Теперь вам нужно контролировать создание вашего объединения, чтобы убедиться, что перечисление установлено правильно, например, с функциями, подобными:
void init_with_struct(struct TestUnionStruct* tus, struct TestStruct const * ts)
{
tus->Part = TUP_STRUCT;
memcpy(&tus->TestUnion.TestStruct, ts, sizeof(*ts));
}
Отправка на правильные значения теперь является одним переключателем:
void print(struct TestUnionStruct const * tus)
{
switch (tus->Part)
{
case TUP_STRUCT:
printf("Num = %u, Name = %s\n",
tus->TestUnion.TestStruct.Num,
tus->TestUnion.TestStruct.Name);
break;
case TUP_TOTAL:
printf("Total = %s\n", tus->TestUnion.Total);
break;
default:
/* Compiler can't make sure you'll never reach this case */
assert(0);
}
}
<Ч />
В качестве примечания хочу отметить, что эти конструкции лучше всего обрабатывать на языках семейства ML.
type test_struct = { num: int; name: string }
type test_union = Struct of test_struct | Total of string