tesis sobre investigaciones investigacion historia caracteristicas c pointers struct unions

sobre - unión de estructuras que comparten los mismos primeros miembros



investigaciones sobre youtube pdf (1)

Después de algunas investigaciones, creo que tengo una respuesta calificada para esta pregunta.

La cita dada fue del estándar C89. C99 y C11 lo han reformulado así:

Se hace una garantía especial para simplificar el uso de las uniones: si una unión contiene varias estructuras que comparten una secuencia inicial común (ver a continuación), y si el objeto de unión contiene actualmente una de estas estructuras, se permite inspeccionar el común parte inicial de cualquiera de ellos en cualquier lugar donde sea visible una declaración del tipo completado de la unión.

La última parte se puede interpretar, en mi humilde opinión, en una variedad de formas. Sin embargo, el comité lo dejó como está. Según ellos, significa que la inspección de la "parte inicial común" de las estructuras solo puede hacerse utilizando un objeto del tipo de union que se haya declarado que las contiene. Eso está muy bien demostrado en esta pregunta .

¿Qué hay de C89, que parece permitir lo que estaba tratando de hacer? Bueno, en un compilador que cumpla con C89, sí, esto debería funcionar. Sin embargo, podría no ser realmente necesario: no conozco un solo compilador estrictamente compatible con C89 que admita un aliasing estricto, por lo que, con ellos, es más fácil simplemente convertir las estructuras con la secuencia inicial común en tipos de los otros y trate de no darles configuraciones de empaque diferentes. El resultado debería ser el mismo.

He estado buscando una forma no tradicional de lograr el "polimorfismo" estructural en el pre-C11 C. Digamos que tenemos 2 estructuras:

struct s1 { int var1; char var2; long var3; }; struct s2 { int var1; char var2; long var3; char var4; int var5; };

En la mayoría de los compiladores, podemos lanzar de manera segura entre punteros a los dos y luego acceder a los primeros miembros comunes si no se produce relleno. Sin embargo, esto no es un comportamiento estandarizado.

Ahora, encontré la siguiente línea en el estándar C en cuanto a C89:

Se hace una garantía especial para simplificar el uso de las uniones: si una unión contiene varias estructuras que comparten una secuencia inicial común, y si el objeto de unión contiene actualmente una de estas estructuras, se permite inspeccionar la parte inicial común de cualquier unión. de ellos. Dos estructuras comparten una secuencia inicial común si los miembros correspondientes tienen tipos compatibles para una secuencia de uno o más miembros iniciales.

También establece lo siguiente:

Un puntero a un objeto de unión, adecuadamente moldeado, apunta a cada uno de sus miembros (o si un miembro es un campo de bits, luego a la unidad en la que reside), y viceversa.

Ahora, si creo una unión de estas dos estructuras:

union s2_polymorphic { struct s1 base; struct s2 derived; };

Y úsalo de esta manera:

union s2_polymorphic test_s2_polymorphic, *ptest_s2_polymorphic; struct s2 *ptest_s2; struct s1 *ptest_s1; ptest_s2_polymorphic = &test_s2_polymorphic; ptest_s2 = (struct s2*)ptest_s2_polymorphic; ptest_s2->var1 = 1; ptest_s2->var2 = ''2''; ptest_s1 = (struct s1*)ptest_s2; printf("ptest_s1->var1 = %d/n", ptest_s1->var1); printf("ptest_s1->var2 = %c/n", ptest_s1->var2);

Que compila y funciona bien y da, en gcc (GCC) 4.8.3 20140911 , la salida

ptest_s1->var1 = 1 ptest_s1->var2 = 2

¿El comportamiento estará bien definido, de acuerdo con las citas de la norma dada anteriormente?