¿Para qué son útiles las estructuras y uniones anónimas en C11?


C11 añade, entre otras cosas, 'Estructuras y Uniones anónimas'.

Miré alrededor pero no pude encontrar una explicación clara de cuándo estructuras anónimas y uniones serían útiles. Pregunto porque no entiendo completamente lo que son. Entiendo que son estructuras o sindicatos sin el nombre después, pero siempre he (¿tenía que?) trate eso como un error, así que solo puedo concebir un uso para estructuras nombradas.

 38
Author: griotspeak, 2012-01-20

5 answers

La unión anónima dentro de las estructuras es muy útil en la práctica. Considere que desea implementar un tipo de suma discriminada (o tagged union), un agregado con un booleano y un flotador o un char* (es decir, una cadena), dependiendo de la bandera booleana. Con C11 debería 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ás que nombrar la unión, y codificar ch->u.f y ch->u.s que es menos legible y más detallado.

 43
Author: Basile Starynkevitch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-16 14:09:40

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;
v.x = 4.0;
v.raw[1] = 3.0; // Equivalent to v.y = 3.0
v.z = 2.0;

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

 33
Author: Emily L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-14 12:53:35
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; } 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
 4
Author: ouah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-19 20:35:02

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 e.a,f.d.b,etc.

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

 0
Author: asaelr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-19 20:24:34
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 está haciendo que por un tiempo - por ejemplo, para compilar este este y este.

 -2
Author: yarek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-19 21:24:03