2010-01-27 6 views
14

El siguiente código:casting una constante a una unión

#include <stdio.h> 

typedef union { 
    int n; 
    char *s; 
} val_t; 

int main(void) { 
    val_t v1,v2; 

    v1 = (val_t)"Hello World"; 
    v2 = (val_t)10; 

    printf("%s %d\n", v1.s, v2.n); 
    return(1); 
} 

compila y ejecuta correctamente con gcc. Si uno intenta lanzar una constante para la cual no hay un campo adecuado en la unión, se produce un mensaje de error.

Sin embargo, mirando el estándar (C99), no he podido localizar la sección donde se describe este comportamiento. Por lo tanto, mi pregunta:

¿La garantía estándar de C que puedo echar una constante para un tipo de unión, siempre que el tipo de unión tiene un campo con un tipo compatible?

o, en otras palabras:

Es un ((val_t)10) rvalue válida de tipo val_t?

También sería interesante saber si este comportamiento es compatible con otros compiladores (o al menos con MS Visual C++). ¿Alguien sabe?

EDITAR: Fundir a una unión es una extensión de GCC, por lo que no es una buena idea usarla.

¡Gracias a Maurits y Neil! ¡No pensé en usar -pedativo para verificar!

+1

Aparte del hecho de que esto parece una mala práctica de programación, es una pregunta interesante. Pensé que después de 20 años de programación en C lo he visto todo, al parecer no :) –

+1

@MauritsRijk En realidad, es una gran manera de implementar contenedores genéricos en C. Haces que la clave del contenedor sea un tipo de unión con campos como int , el puntero doble y vacío, y la función de comparador que usted transfiere sabe qué tipo necesita y accede al miembro apropiado de la unión. De hecho, no veo por qué no es una parte estándar del lenguaje, ya que la forma en que se definen las uniones en K & R, cada miembro se alinea con la dirección más baja, se garantiza que la unión tenga una alineación de memoria adecuada para todos sus miembros, y lo suficientemente ancho como para contener el más ancho. –

Respuesta

5

En GNU C language extensions la fundición a una unión se marca como una extensión del estándar C. Por lo tanto, lo más probable es que no lo encuentres en el C99 o en cualquier otro estándar de C. El compilador de IBM C también es compatible con esta extensión.

5
[[email protected] NeilB]$ gcc -Wall -pedantic sw.c 
sw.c: In function 'main': 
sw.c:11: warning: ISO C forbids casts to union type 
sw.c:12: warning: ISO C forbids casts to union type 
Cuestiones relacionadas