estructuras 'punning' de unión con “secuencia inicial común”: ¿Por qué C (99+), pero no C ++, estipula una 'declaración visible del tipo de unión'?
Debates sobre la naturaleza, en su mayoría, no definida o implementada de la escritura de tipos mediante ununion
normalmente cita los siguientes bits, aquí a través de @ecatmur (https://stackoverflow.com/a/31557852/2757035 ), en una exención para el diseño estándarstruct
s que tiene una "secuencia inicial común" de tipos de miembros:
C11 (6.5.2.3 Estructura y miembros del sindicato; Semántica):
[...] si una unión contiene varias estructuras que comparten una secuencia inicial común (ver abajo), y si el objeto de unión actualmente contiene una de estas estructuras, se permite inspeccionar la parte inicial común de cualquiera de ellas.en cualquier lugar que sea visible una declaración del tipo completo de la unión. Dos estructuras comparten unsecuencia inicial común si los miembros correspondientes tienen tipos compatibles (y, para campos de bits, los mismos anchos) para una secuencia de uno o más miembros iniciales.
C ++ 03 ([class.mem] / 16):
Si una unión POD contiene dos o más estructuras POD que comparten una secuencia inicial común, y si el objeto de unión POD actualmente contiene una de estas estructuras POD, se permite inspeccionar la parte inicial común de cualquiera de ellas. Dos estructuras POD comparten una secuencia inicial común si los miembros correspondientes tienen tipos compatibles con el diseño (y, para campos de bits, los mismos anchos) para una secuencia de uno o más miembros iniciales.
Otras versiones de los dos estándares tienen un lenguaje similar; desde C ++ 11 la terminología utilizada esdiseño estándar más bien queVAINA.
Como no se requiere una reinterpretación, esto no es realmente un tipo de letra, solo se aplica la sustitución de nombre aunion
accesos de miembros. Una propuesta para C ++ 17 (el infame P0137R1) lo hace explícito usando un lenguaje como 'el acceso es como si el otro miembro de la estructura estuviera nominado'.
Pero tenga en cuenta el negrita - "en cualquier lugar que sea visible una declaración del tipo completo de la unión"- una cláusula que existe en C11 pero en ninguna parte de los borradores de C ++ para 2003, 2011 o 2014 (todas casi idénticas, pero las versiones posteriores reemplazan" POD "con el nuevo términodiseño estándar) En cualquier caso, la 'declaración visible deunion
el bit de tipo está totalmente ausente en la sección correspondiente de cualquier estándar de C ++.
@loop y @ Mints97, aquí:https://stackoverflow.com/a/28528989/2757035 - demuestre que esta línea también eraausente en C89, apareciendo por primera vez en C99 y permaneciendo en C desde entonces (aunque, nuevamente, nunca filtrándose a C ++).
Discusiones de estándares sobre esto[recortado - mira mi respuesta]
PreguntasA partir de esto, entonces, mis preguntas fueron:
¿Qué significa esto? ¿Qué se clasifica como una 'declaración visible'? ¿Esta cláusula tenía la intención de reducir, o ampliar, el rango de contextos en los que ese 'castigo' ha definido el comportamiento?
¿Debemos suponer que esta omisión en C ++ es muy deliberada?
¿Cuál es la razón para que C ++ difiera de C? ¿C ++ simplemente 'heredó' esto de C89 y luego decidió, o peor,olvidar - para actualizar junto con C99?
Si la diferencia es intencional, entonces¿Qué beneficios o inconvenientes hay para los 2 tratamientos diferentes en C vs C ++?
¿Qué ramificaciones interesantes, si es que tiene, tiene en tiempo de compilación o tiempo de ejecución? Por ejemplo, @ecatmur, en un comentario respondiendo a mi señalando esto en su respuesta original (enlace como arriba), especuló de la siguiente manera.
Me imagino que permite una optimización más agresiva; C puede asumir que los argumentos de la funciónS* s
yT* t
no alias incluso si comparten una secuencia inicial común siempre que nounion { S; T; }
está a la vista, mientras que C ++ puede hacer esa suposición solo en el momento del enlace. Podría valer la pena hacer una pregunta por separado sobre esa diferencia.
Bueno, aquí estoy, preguntando! Estoy muy interesado en cualquier idea sobre esto, especialmente: otras partes relevantes del Estándar (cualquiera), citas de miembros del comité u otros comentaristas estimados, ideas de desarrolladores que podrían haber notado una diferencia práctica debido a esto, suponiendo que cualquier compilador inclusomolesta para hacer cumplir la cláusula agregada de C - y etc. El objetivo es generar un catálogo útil de hechos relevantes sobre esta cláusula C y su omisión (intencional o no) de C ++. ¡Entonces vamos!