¿Es posible (legales) para asignar una unión anónima en un compuesto literal?
-
19-09-2019 - |
Pregunta
Tengo una estructura:
typedef struct _n
{
int type;
union {
char *s;
int i;
};
} n;
Cuando intento para asignar un compuesto literal, como:
node n1 = {1, 0};
node n2 = {2, "test"};
gcc me da algunas advertencias tales como:
warning: initialization makes pointer from integer without a cast
warning: initialization from incompatible pointer type
Bueno, está claro que el compilador no está seguro acerca de mí acabo la asignación de un valor a un tipo posiblemente ambigua. Sin embargo, incluso si trato de especificar con mayor precisión:
node n0 = {type: 1, i: 4};
Me sale:
error: unknown field ‘i’ specified in initializer
He leído que si pongo (union <union name>)
antes i:
entonces se puede trabajar. Sin embargo, yo prefiero tener una unión anónima. ¿Hay una manera de hacerlo?
Solución
Los sindicatos anónimos no son estándar de C - que son una extensión del compilador. No te recomiendo dando la unión de un nombre. Si usted insiste en el uso de una unión anónima, a continuación, sólo se puede dar un inicializador para el primer elemento de la misma:
node n0 = {1, 0}; // initializes `s' to 0
Cuando se compila con -Wall -Wextra -pedantic
, gcc me dio la advertencia "llaves alrededor del inicializador desaparecidos", que es una advertencia válida. El inicializador en realidad se debe especificar la siguiente manera:
node n0 = {1, {0}}; // initializes `s' to 0
Ahora bien, esto sólo se da una advertencia de que "ISO C no soporta sin nombre structs / sindicatos".
Si le das a la unión de un nombre, entonces se puede utilizar una función llamada C99 inicializadores designados para inicializar un miembro específico de la unión:
typedef struct
{
int type;
union {
char *s;
int i;
} value;
} node;
node n0 = {1, { .s = "string"; }};
node n1 = {2, { .i = 123; }};
Es necesario la unión de tener un nombre; de lo contrario, el compilador se quejará por el inicializador designado en su interior.
La sintaxis que estaba tratando de utilizar node n0 = {type: 1, i: 4}
es una sintaxis no válida; parece que estuviera tratando de utilizar inicializadores designados.