объявление 1: Да, это будет работать.
объявление 2: да, оно идеально определено.
объявление 3: да, это законно.
Вся идея union
заключается в том, что он может содержать различные типы элементов. Размер объединения будет размером самого большого элемента в объединении. В 64-битной системе это, вероятно, будет размер char *
.
Так что нет, компилятор не будет предполагать, что все элементы являются указателями на символы. Вот почему вы должны использовать точку с точкой, чтобы указать компиляции в вашем операторе, к какому типу элемента вы хотите обращаться, и компилятор сгенерирует доступ.
Но, как сказал Том, вы не можете знать, какой тип элемента в данный момент хранится; должна быть внешняя причина (информация), по которой вы это знаете. Если это важно знать, вы должны хранить информацию в структуре данных, например:
typedef struct {
int whatisthis;
union {
int foo;
char *bar;
} u;
} int_or_str;
и установите его следующим образом:
int_or_str example;
example.whatisthis= 1;
example.u.foo= 1;
example.whatisthis= 2;
example.u.bar= "test";
и доступ как:
if (example.whatisthis==1) printf("%d\n", example.u.foo);
if (example.whatisthis==2) printf("%s\n", example.u.bar);