Нет правильного поведения.Установка объединения через одного члена и получение значения из другого члена вызывает неопределенное поведение.С помощью этой техники вы можете делать полезные вещи, но она очень зависит от аппаратного обеспечения и компилятора.Вам нужно будет учитывать требования к порядку байтов процессора и выравниванию памяти.
В те времена, когда я почти все программировал на C, было два (переносимых) метода, использующих союзы, на которые я довольно сильно полагался.* помеченный союз .Это здорово, когда вам нужна динамически типизированная переменная.Вы устанавливаете структуру с двумя полями: дискриминант типа и объединение всех возможных типов.
struct variant {
enum { INT, CHAR, FLOAT } type;
union value {
int i;
char c;
float f;
};
};
Вам просто нужно было быть очень осторожным, чтобы правильно установить значение типа при каждом изменении значения объединения иполучить только значение, указанное типом.
Общие указатели .Поскольку вы можете быть совершенно уверены, что все указатели имеют одинаковый размер и представление, вы можете создать объединение типов указателей и знать, что вы можете устанавливать и получать значения взаимозаменяемо, независимо от типа:
typedef union {
void *v;
int* i;
char* c;
float* f;
} ptr;
Этоособенно полезно для (де) сериализации двоичных данных:
// serialize
ptr *p;
p.v = ...; // set output buffer
*p.c++ = 'a';
*p.i++ = 12345;
*p.f++ = 3.14159;
// deserialize
ptr *p;
p.v = ...; // set input buffer
char c = *p.c++;
int i = *p.i++;
float f = *p.f++;
К вашему сведению: Вы можете упростить свой пример.Структуры не нужны.Вы получите то же поведение с этим:
int main() {
union {
int a;
char b;
} v1;
v1.a = 5;
v1.b = 'a';
}