¿Por qué C ++ no permite estructuras anónimas?

Algunos comstackdores de C ++ permiten uniones y uniones anónimas como una extensión de C ++ estándar. Es un poco de azúcar sintáctico que ocasionalmente es muy útil.

¿Cuál es la razón que impide que esto sea parte del estándar? ¿Hay un locking técnico? ¿Uno filosófico? ¿O simplemente no es suficiente la necesidad de justificarlo?

Aquí hay una muestra de lo que estoy hablando:

struct vector3 { union { struct { float x; float y; float z; }; float v[3]; }; }; 

Mi comstackdor aceptará esto, pero advierte que “struct / union sin nombre” es una extensión no estándar de C ++ .

Como otros han señalado, las uniones anónimas están permitidas en C ++ estándar, pero las estructuras anónimas no lo son.

La razón de esto es que C admite uniones anónimas pero no estructuras anónimas *, por lo que C ++ admite la compatibilidad pero no la última porque no es necesaria para la compatibilidad.

Además, no hay mucho uso para las estructuras anónimas en C ++. El uso que demuestras, para tener una estructura que contiene tres flotantes a los que se puede hacer referencia por .v[i] , o .x , .y y .z , creo que da como resultado un comportamiento indefinido en C ++. C ++ no le permite escribir a un miembro de una unión, digamos .v[1] , y luego leer de otro miembro, digamos .y . Aunque el código que hace esto no es raro, en realidad no está bien definido.

Las instalaciones de C ++ para tipos definidos por el usuario brindan soluciones alternativas. Por ejemplo:

 struct vector3 { float v[3]; float &operator[] (int i) { return v[i]; } float &x() { return v[0]; } float &y() { return v[1]; } float &z() { return v[2]; } }; 

* C11 aparentemente agrega estructuras anónimas, por lo que una futura revisión de C ++ puede agregarlas.

Diré, puedes limpiar tu statement vector3 simplemente usando un union

 union vector3 { struct { float x, y, z; } ; float v[3] ; } ; 

Claro, las estructuras anónimas eran una extensión de MSVC . Pero ISO C11 lo permite ahora, y gcc lo permite , y también lo hace el comstackdor llvm de Apple.

¿Por qué en C11 y no en C ++ 11? No estoy seguro, pero prácticamente la mayoría (comstackdores C ++ de gcc ++, MSVC ++ y comstackdor C ++ de Apple) los admiten.

No estoy seguro de lo que quieres decir. Sección 9.5 de la especificación C ++, cláusula 2:

Una unión de la forma

 union { member-specification } ; 

se llama una unión anónima; define un objeto sin nombre de tipo sin nombre.

Usted puede hacer cosas como esta también:

 void foo() { typedef struct { // unnamed, is that what you mean by anonymous? int a; char b; } MyStructType; // this is more of a "C" style, but valid C++ nonetheless struct { // an anonymous struct, not even typedef'd double x; double y; } point = { 1.0, 3.4 }; } 

No siempre es muy útil … aunque a veces es útil en desagradables definiciones macro.

Los sindicatos pueden ser anónimos; ver el Estándar, 9.5 párrafo 2.

¿Qué propósito considera que cumple una estructura o clase anónima? Antes de especular sobre por qué algo no está en el Estándar, me gustaría tener una idea de por qué debería ser así, y no veo el uso para una estructura anónima.

Basándome en la edición, los comentarios y este artículo de MSDN: Estructuras anónimas , me arriesgaré a suponer que encaja mal con el concepto de encapsulación. No esperaría que un miembro de una clase se metiera con el espacio de nombres de mi clase más allá de simplemente agregar un miembro. Además, los cambios en la estructura anónima pueden afectar mi clase sin permiso.

Tu codigo

 union { struct { float x; float y; float z; }; float v[3]; }; 

es como

 union Foo { int; float v[3]; }; 

que seguramente no es válido (en C99 y antes).

La razón probablemente sea para simplificar el análisis sintáctico (en C), porque en ese caso solo necesita verificar que el cuerpo struct / union solo tenga “declaraciones de declaradores” como

 Type field; 

Dicho esto, gcc y “otros comstackdores” admiten campos sin nombre como una extensión.

Editar: las estructuras anónimas ahora se admiten oficialmente en C11 (§6.7.2.1 / 13).