2011-05-28 17 views
7

Estoy intentando globalmente inicializar una unión como en el siguiente ejemplo:unión inicialización

#include <cstdio> 

typedef union { 
    char t[4]; 
    int i; 
} a; 

enum { 
    w = 5000, 
    x, 
    y, 
    z 
}; 

a temp = {w}; 
int main() { 
    printf("%d %d %d %d %d\n", temp.t[0],temp.t[1],temp.t[2],temp.t[3],temp.i); 
    return 0; 
} 

Sin embargo, si ejecuta el código, se le nota que ninguno de temp.i o temp.t [ ...] realmente dan el ítem correcto con el que inicié la unión. Imagino que esto se evitaría si pudiera inicializar manualmente el miembro entero, pero desafortunadamente no puedo. Tampoco puedo cambiar el orden de los elementos dentro de la estructura (el intercambio de las órdenes int y char inicializa todo correctamente) - en realidad son proporcionados por una biblioteca externa. Mi pregunta es: ¿cómo puedo establecer el miembro entero de la estructura globalmente, en lugar del miembro char [4] (o, en este caso, solo el primer elemento del char [])?

EDITAR: ¿Existe también una solución estrictamente C++ para este problema? es decir, una donde la inicialización de struct llamada no funciona (porque no existe en el lenguaje)?

Respuesta

7

que se quiere hacer esto:

a temp = {i: w}; 

que debería trabajo para ambos gcc y g++.

+0

Ah, la belleza; Esto es lo que estaba buscando. Cheers –

+3

Tenga en cuenta que esta es una extensión de idioma no estándar, y que si se mueve a otros compiladores, esto fallará. –

+0

Sí, por eso mencioné gcc/g ++. No parece haber un método válido de C++ para inicializar los miembros de la unión. – evgeny

11

En el C99 se puede hacer esto:

a temp = { .i=w }; 
6

Usted puede inicializar el miembro de número entero de esta manera:

a temp = { 
    .i = w 
}; 
7

En C99 que puede hacer uso el nombre de inicialización como en:

a x = { .i = 10 }; 

Hay alguna sugerencia para el uso de la extensión gcc no estándar, pero me gustaría evitar que si la codificación C:

a x = { i : 10 }; 

puede utilizar una función para inicializar:

inline a initialize(int value) { // probably choose a better name 
    a tmp; 
    tmp.i = value; 
    return a; 
} 

y luego usar:

a x = initialize(10); 

El compilador optimizará las copias de distancia.

Si usted está haciendo C++, puede proporcionar un constructor para su tipo de unión:

/*typedef*/ union u {   // typedef is not required in general in C++ 
    char bytes[sizeof(int)]; 
    int i; 
    u(int i = 0) : i(i) {} 
} /*u*/; 

u x(5); 
+0

El problema es que no puedo modificar la unión en sí; de lo contrario, reorganizaría los elementos y terminaría. Aunque me gusta el enfoque en línea. –