¿Para qué sirven las estructuras anónimas y las uniones en C11?

C11 agrega, entre otras cosas, ‘Estructuras y sindicatos anónimos’.

Busqué pero no pude encontrar una explicación clara de cuándo serían útiles las estructuras anónimas y los sindicatos. Lo pregunto porque no entiendo completamente lo que son. Entiendo que son estructuras o uniones sin el nombre después, pero siempre he tenido que (¿tener que hacerlo?) Tratar esto como un error, así que solo puedo concebir un uso para las estructuras con nombre.

La unión anónima dentro de las estructuras es muy útil en la práctica. Considere que desea implementar un tipo de sum discriminado (o unión etiquetada ), un agregado con un booleano y un flotante o un char* (es decir, una cadena), según el indicador booleano. Con C11 deberías ser capaz de codificar

 typedef struct { bool is_float; union { float f; char* s; }; } mychoice_t; double as_float(mychoice_t* ch) { if (ch->is_float) return ch->f; else return atof(ch->s); } 

Con C99, tendrá que nombrar la unión y codificar ch->uf y ch->us que es menos legible y más detallado.

Un uso típico y real de estructuras y uniones anónimas es proporcionar una vista alternativa a los datos. Por ejemplo, al implementar un tipo de punto 3D:

 typedef struct { union{ struct{ double x; double y; double z; }; double raw[3]; }; }vec3d_t; vec3d_t v; vx = 4.0; v.raw[1] = 3.0; // Equivalent to vy = 3.0 vz = 2.0; 

Esto es útil si interactúa con un código que espera un vector 3D como un puntero a tres dobles. En lugar de hacer f(&v.x) que es feo, puedes hacer f(v.raw) que hace que tu bash sea claro.

 struct bla { struct { int a; int b; }; int c; }; 

el tipo struct bla tiene un miembro de un tipo de estructura anónima C11.

struct { int a; int b; } struct { int a; int b; } no tiene etiqueta y el objeto no tiene nombre: es un tipo de estructura anónima.

Puede acceder a los miembros de la estructura anónima de esta manera:

 struct bla myobject; myobject.a = 1; // a is a member of the anonymous structure inside struct bla myobject.b = 2; // same for b myobject.c = 3; // c is a member of the structure struct bla 

Bueno, si declaras variables de esa estructura solo una vez en tu código, ¿por qué necesita un nombre?

 struct { int a; struct { int b; int c; } d; } e,f; 

Y ahora puedes escribir cosas como ea , fdb , etc.

(Agregué la estructura interna, porque creo que este es uno de los usos más comunes de las estructuras anónimas)

 struct Lock; int lock(Lock*); ... struct Queue { Lock; char buf[QBUFSIZE]; char *rp; char *wp; } qputc(Queue* q, char c){ lock(q); ... } 

update3 : ken c hace eso por un tiempo, por ejemplo, para comstackr esto y esto .