Mezclando clase y estructura

Soy muy consciente de la diferencia entre clase y estructura , sin embargo, estoy luchando por decir con autoridad si esto está bien definido:

// declare foo (struct) struct foo; // define foo (class) class foo { }; // instance of foo, claiming to be a struct again! Well defined? struct foo bar; // mixing class and struct like this upsets at least one compiler (names are mangled differently) const foo& test() { return bar; } int main() { test(); return 0; } 

Si esto es un comportamiento indefinido, ¿alguien puede dirigirme hacia una referencia autorizada (es decir, capítulo y versículo de ISO)?

El comstackdor con problemas para manejar esto ( Carbide 2.7 ) es relativamente viejo y todos los otros comstackdores en los que lo probé están perfectamente contentos con esto, pero claramente eso no prueba nada.

Mi intuición era que este comportamiento debería ser indefinido, pero no puedo encontrar nada que lo confirme y me sorprende que ninguna de las versiones de GCC o Comeau lo haya advertido.

    Me parece que es un comportamiento definido. En particular, §9.1 / 2 dice:

    Una statement que consiste únicamente class-key identifier ; de class-key identifier ; es una restatement del nombre en el ámbito actual o una statement directa del identificador como nombre de clase. Introduce el nombre de la clase en el scope actual.

    El estándar distingue entre usar class , struct o union al definir una clase, pero aquí, al hablar de una statement, no se hace tal distinción: usar una class-key es equivalente a cualquier otra.

    Desde Advertencia C4099: nombre de tipo visto por primera vez usando ‘clase’ ahora visto usando ‘struct’ (MS VS 2k8) parece que al menos algunos comstackdores se deshacen de forma diferente dependiendo de la palabra clave utilizada, así que mejor no confiar en ella incluso si está técnicamente permitida ( de los cuales no puedo encontrar una referencia de confirmación).

    Técnicamente, el código está bien, de acuerdo con el estándar de idioma. Sin embargo, como al menos uno de los comstackdores más populares emite una advertencia al respecto, no funciona en la práctica.

    “En teoría, no hay diferencia entre la teoría y la práctica. En la práctica, la hay”.

    En C ++, una estructura es una clase. Específicamente:

    Una estructura es una clase definida con la struct clave de clase. (ISO / IEC FDIS 14882: 1998 (E) 9-4)

    Esto implica que su clase, que no se definió con struct , definitivamente no es una estructura. Por lo tanto, su statement forward con la struct clase-clave es errónea. No conozco ninguna parte de la especificación que permita que una statement directa utilice una clave de clase claramente errónea. Estoy seguro de que los comstackdores indulgentes en cuestión tratan las estructuras y las clases por igual y están pasando por alto la statement incorrecta. Es posible que no se requiera un error del comstackdor en este escenario, pero tampoco debe ser inesperado.

    No tengo idea si esto no está definido (o cualquiera de las otras categorías de no-conformarse estrictamente) según el estándar C, pero sí sé que si tienes dos unidades de traducción que no concuerdan si un tipo ‘ foo ‘se declara como una’ clase ‘o una’ estructura ‘, así:

    TU 1

     struct foo; void f(foo&) { ... } 

    TU 2

     class foo { ... }; void f(foo&); void g() { foo x; f(x); } 

    entonces, al menos algunos comstackdores (notablemente MSVC ++) cambiarán el nombre de f diferente en cada unidad de traducción, por lo que la definición de f en TU 1 no satisface la referencia a f en TU 2 y se obtiene un error de enlace. Esto aparece en la vida real cuando tienes un encabezado Ah que define la clase A y necesita referirse a las clases B , C y D pero una statement directa de ellas es suficiente (por lo que, con bastante sensatez, no incluye Bh etc.) – es mejor utilizar la misma palabra clave para esas declaraciones avanzadas que las definiciones reales!

    MSVC10 arroja una advertencia y la página de advertencia indica que se usará el tipo dado en la definición.

    http://msdn.microsoft.com/en-us/library/695x5bes.aspx