ejemplos - c++ online
¿Están estándar los "esquemas anónimos"? Y, realmente, ¿qué*son*ellos? (3)
MSDN reckons que las estructuras anónimas no son estándar en C ++:
Una extensión de Microsoft C le permite declarar una variable de estructura dentro de otra estructura sin darle un nombre. Estas estructuras anidadas se llaman estructuras anónimas. C ++ no permite estructuras anónimas.
Puede acceder a los miembros de una estructura anónima como si fueran miembros en la estructura contenedora.
Me dijeron que esta característica no es necesariamente lo mismo que simplemente crear una estructura sin nombre, pero no puedo ver una distinción en términos de redacción estándar.
C ++ 11 dice:
[C++11: 9/1]
: [..] Un especificador de clase cuyo nombre de clase omite el nombre de cabecera de clase define una clase sin nombre.
y proporciona una construcción gramatical completa para una definición de tipo que carece de un nombre.
C ++ 03 carece de esta redacción explícita, pero de manera similar indica que el identifier
en una definición de tipo es opcional y hace referencia a "clases sin nombre" en 9.4.2/5
y 3.5/4
.
- Entonces, ¿MSDN está equivocado, y estas cosas son completamente estándar?
- ¿O hay alguna sutileza que me falta entre las "estructuras / clases sin nombre" y lo mismo cuando se usan como miembros que les impide estar cubiertos por esta funcionalidad de C ++ 03 / C ++ 11?
- ¿Me estoy perdiendo alguna diferencia fundamental entre "estructura sin nombre" y "estructura anónima"? Parecen sinónimos para mí.
La norma habla de uniones anónimas : [9.5] / 5
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. La especificación de miembro de una unión anónima solo debe definir miembros de datos no estáticos. [Nota: los tipos anidados y las funciones no se pueden declarar dentro de una unión anónima. -finalización] Los nombres de los miembros de una unión anónima serán distintos de los nombres de cualquier otra entidad en el ámbito en que se declare la unión anónima. A los efectos de la búsqueda de nombres, después de la definición anónima de unión, se considera que los miembros de la unión anónima se han definido en el ámbito en el que se declara la unión anónima. [Ejemplo:
void f() { union { int a; const char* p; }; a = 1; p = "Jennifer"; }
Aquí a y p se usan como variables ordinarias (no miembros), pero dado que son miembros de la unión, tienen la misma dirección. -Final ejemplo]
Las estructuras anónimas de las que Microsoft habla es esta característica para los unions
pero se aplica a las structs
. No es solo una definición sin nombre, es importante tener en cuenta que los miembros de la unión / estructura anónima se consideran definidos en el ámbito en el que se declara la unión / estructura anónima.
Hasta donde yo sé, no existe tal comportamiento para las estructuras anónimas en el Estándar. Observe cómo en el ejemplo citado puede lograr cosas que de otro modo no serían posibles, como compartir el almacenamiento de las variables en la pila, mientras que las estructuras anónimas no aportan nada nuevo a la tabla.
Las cosas que Microsoft llama estructuras anónimas no son estándar. Una estructura sin nombre es solo una estructura ordinaria que no tiene un nombre. No hay mucho que pueda hacer con uno, a menos que también defina un objeto de ese tipo:
struct {
int i;
double d;
} my_object;
my_object.d = 2.3;
Los sindicatos anónimos son parte del estándar, y tienen el comportamiento que usted esperaría al leer la descripción de Microsoft de sus estructuras anónimas:
union {
int i;
double d;
};
d = 2.3;
Todo el texto estándar se refiere a la creación de una "estructura sin nombre":
struct {
int hi;
int bye;
};
Solo un buen tipo amigable, sin nombre accesible.
De forma estándar, se podría instanciar como un miembro como este:
struct Foo {
struct {
int hi;
int bye;
} bar;
};
int main()
{
Foo f;
f.bar.hi = 3;
}
Pero una "estructura anónima" es sutilmente diferente: es la combinación de una "estructura sin nombre" y el hecho de que mágicamente obtienes miembros en el objeto principal:
struct Foo {
struct {
int hi;
int bye;
}; // <--- no member name!
};
int main()
{
Foo f;
f.hi = 3;
}
Inversa a la intuición † , esto no crea simplemente una estructura sin nombre anidada en Foo
, sino que también le proporciona automáticamente un "miembro anónimo" que permite que los miembros sean accesibles dentro del objeto principal.
Es esta funcionalidad que no es estándar. GCC lo admite , al igual que Visual C ++. Los encabezados de la API de Windows hacen uso de esta característica de manera predeterminada, pero puede especificar que no la quiere añadiendo #define NONAMELESSUNION
antes de incluir los archivos de encabezado de Windows.
Compare con la funcionalidad estándar de "uniones anónimas" que hacen algo similar:
struct Foo {
union {
int hi;
int bye;
}; // <--- no member name!
};
int main()
{
Foo f;
f.hi = 3;
}
† Parece que, aunque el término "sin nombre" se refiere al tipo (es decir, "la clase" o "la estructura") en sí, el término "anónimo" se refiere al miembro ejemplificado real (utilizando un significado anterior de "la estructura "eso está más cerca de" un objeto de algún tipo de struct
"). Esta fue probablemente la raíz de tu confusión inicial.