La diferencia es que el segundo no es válido.
Las cosas entre {
y }
en una declaración struct son una secuencia de declaraciones de miembros. Su
struct myinnerstruct
{
int y;
};
es una declaración de tipo; no declara un miembro de la estructura adjunta, por lo que es ilegal en ese contexto.
Lo que puede hacer es esto:
struct mystruct
{
int x;
struct myinnerstruct
{
int y;
} m;
};
La declaración de m
es una declaración de miembro, así que está bien; también declara el tipo struct myinnerstruct
. Pero en mi opinión, es un estilo pobre. El tipo struct myinnerstruct
permanece visible después de que se completa la declaración de struct mystruct
; ver abajo para la explicación.
Si realmente quieres una estructura dentro de una estructura como esa, y no se va a utilizar struct myinnerstruct
en otro sitio, usted podría dejarlo sin una etiqueta:
struct mystruct
{
int x;
struct
{
int y;
} m;
};
Pero entonces puede ser que también declarar y
como miembro de struct mystruct
.
Si desea que struct innerstruct
sea un tipo con nombre, simplemente explíquelo por separado, como lo hizo en su primer ejemplo.
Aquí está la explicación de por quéstruct innerstruct
permanece visible.
El C99 standard (grande PDF), sección 6.2.1 párrafo 2, dice:
Para cada entidad diferente que designa un identificador, el identificador es visible (es decir, se puede utilizar) solamente dentro de una región de texto del programa llamado ámbito. Las diferentes entidades designadas por el mismo identificador tienen diferentes ámbitos o están en espacios de nombre diferente .Hay cuatro tipos de ámbitos: función, archivo, bloque y prototipo de función . (Un prototipo de la función es una declaración de una función que declara los tipos de sus parámetros.)
Las normas C90 y C11 tienen esencialmente la misma redacción.
{
llaves }
en una declaración de estructura no definen un bloque, ni definen ninguno de los otros tipos posibles de ámbito, por lo que cualquier cosa declarada entre llaves no tiene alcance en esa región; debe tener un alcance en algún contexto circundante. Sucede que la sintaxis le permite declarar struct myinnerstruct
dentro de otra definición de estructura, pero solo si es parte de una definición de miembro. Creo que esto solo está permitido porque los diseñadores del lenguaje no hicieron ningún esfuerzo adicional para rechazarlo; es solo un efecto secundario de otras reglas. Usted puede hacerlo, pero no lo recomiendo.
¿La segunda variante es incluso legal C? –
No he podido encontrar ningún ejemplo en línea. Mis pruebas para ambos devuelven los mismos resultados. Así que AFAIK, lo es. – prelic
Lo siguiente también funcionaría, para hacer que el segundo sea un poco más corto: 'struct mystruct {int x; struct myinnerstruct {int y; } m; }; En mi humilde opinión, la mejor razón para definir una 'struct' dentro de otra' struct' es cuando la 'struct' interna se utiliza exclusivamente y quizás repetidamente como miembro de la' struct' externa, es decir, cuando una 'struct' tiene que tener muchos "grupos" que almacenan información similar para diferentes propósitos. –