c language-lawyer c11

¿Se han descrito incorrectamente las estructuras y uniones anónimas en C11?



language-lawyer (1)

Dice el estándar C, con respecto a estructuras anónimas y uniones:

6.7.2.1 p13. Un miembro sin nombre cuyo especificador de tipo es un especificador de estructura sin etiqueta se denomina estructura anónima; un miembro sin nombre cuyo especificador de tipo es un especificador de unión sin etiqueta se denomina unión anónima. Los miembros de una estructura o unión anónima se consideran miembros de la estructura o unión que los contiene. Esto se aplica recursivamente si la estructura que contiene o la unión también es anónima.

Tenga en cuenta el énfasis: en lugar de que los miembros de la estructura / unión anónima estén dentro del alcance de la estructura / unión de contención, son miembros de la misma. Pero hay responsabilidades adjuntas a eso:

6.7.2.1 p16. El tamaño de un sindicato es suficiente para contener al mayor de sus miembros. El valor de como máximo uno de los miembros puede almacenarse en un objeto de unión en cualquier momento. Un puntero a un objeto de unión, adecuadamente convertido, 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.

Tomados en conjunto, parecen implicar que los miembros de una estructura anónima dentro de una unión (nombrada) se comportan como miembros de la unión que son co-localizados y se excluyen mutuamente. Así que lo siguiente debería funcionar:

union Foo { struct { char a; char b; }; }; int main(void) { union Foo f; assert(&f == &(f.a) && &f == &(f.b)); }

Por supuesto, no es así, y no quisiéramos que ... no habría ninguna razón para estructuras / sindicatos anónimos si funcionaran como antes. Aún así, el Estándar parece inequívoco en ese punto. ¿Se me escapa algo?


TL; DR

Esto parece un problema de redacción, no deben superponerse.

Detalles

Esto está cubierto en el Informe de Defectos (DR) 499 que pregunta:

Dado el siguiente código:

union U { struct { char B1; char B2; char B3; char B4; }; int word; } u;

¿Se superpone el almacenamiento de B1, B2, B3 y B4?

De acuerdo con 6.7.2.1 # 13, los miembros deben superponerse en el almacenamiento a medida que se convierten en miembros de ''union U''.
Al menos una implementación (GCC) parece NO considerar que se solapan.
Al menos una implementación (el XL LE AIX de IBM) considera que están superpuestas como el estándar actualmente establece.

Y la respuesta de los comités fue:

El almacenamiento no se superpone.

Un problema relacionado se encuentra en el DR 502 y ambos pueden resolverse con cambios de redacción coordinados.

y

Cambie §6.7.2.1 p13 de:

Un miembro sin nombre de tipo de estructura sin etiqueta se llama estructura anónima; un miembro no identificado de tipo sindical sin etiqueta se denomina unión anónima. Los miembros de una estructura o unión anónima se consideran miembros de la estructura o unión que los contiene. Esto se aplica recursivamente si la estructura que contiene o la unión también es anónima.

a:

Un miembro sin nombre de tipo de estructura sin etiqueta se llama estructura anónima; un miembro no identificado de tipo sindical sin etiqueta se denomina unión anónima. Los nombres de los miembros de una estructura o unión anónima se agregan al espacio de nombres de la estructura o unión que lo contiene. Esto se aplica recursivamente si la estructura que contiene o la unión también es anónima.

resolvería adecuadamente el problema.