É possível (legal) para atribuir uma união anônima em um literal composto?
-
19-09-2019 - |
Pergunta
Eu tenho uma struct:
typedef struct _n
{
int type;
union {
char *s;
int i;
};
} n;
Quando eu tentar atribuir um literal composto, como:
node n1 = {1, 0};
node n2 = {2, "test"};
gcc me dá alguns avisos tais como:
warning: initialization makes pointer from integer without a cast
warning: initialization from incompatible pointer type
Bem, é claro que o compilador não tem certeza sobre mim apenas atribuir um valor a um tipo possivelmente ambígua. No entanto, mesmo se eu tentar especificar mais precisamente:
node n0 = {type: 1, i: 4};
eu recebo:
error: unknown field ‘i’ specified in initializer
Eu li que se eu colocar (union <union name>)
antes i:
então ele pode trabalhar. No entanto, eu prefiro ter uma união anônima. Existe uma maneira de fazê-lo?
Solução
anônimos não são padrão C - eles são uma extensão do compilador. Eu recomendaria fortemente dando a união de um nome. Se você insistir em usar uma união anônima, então você só pode dar um inicializador para o primeiro elemento do mesmo:
node n0 = {1, 0}; // initializes `s' to 0
Quando compilado com -Wall -Wextra -pedantic
, gcc me deu o aviso "chaves faltando em torno initializer", que é um aviso válido. O inicializador deve realmente ser especificado como isto:
node n0 = {1, {0}}; // initializes `s' to 0
Agora, isso só dá um aviso de que "ISO C não suporta sem nome structs / sindicatos".
Se você der a união de um nome, então você pode usar um recurso chamado C99 inicializadores designados para inicializar um membro específico da união:
typedef struct
{
int type;
union {
char *s;
int i;
} value;
} node;
node n0 = {1, { .s = "string"; }};
node n1 = {2, { .i = 123; }};
Você precisa do sindicato para ter um nome; Caso contrário, o compilador vai reclamar sobre o designado initializer dentro dela.
A sintaxe que você estava tentando usar node n0 = {type: 1, i: 4}
é uma sintaxe inválida; parece que você estava tentando usar inicializadores designados.