-3

I would like to know why and when one would explicitly choose to use an anonymous structure like so:

typedef struct my_struct_t my_struct_t;

struct my_struct_t
{
    int a;
    int b;
};

int main()
{   

    my_struct_t obj1 =
    {
        .a = 33,
        .b = 44
    };

    return 0; 
}

rather than doing:

typedef struct my_struct_t my_struct_t;

struct my_struct_t
{
    int a;
    int b;
};

int main()
{   

    my_struct_t obj2;
    obj2.a = 55;
    obj2.b = 66;

    return 0; 
}

What advantages does the former offer over the latter and/or vice-verca? thanks

  • 11
    There is no anonymous structure in either of your codes. – Eugene Sh. Jan 17 '18 at 21:21
  • 2
    That's an initializer list, not an anonymous structure. – Barmar Jan 17 '18 at 21:21
  • it just means you don't have to repeat `obj2.` for every member. This becomes more valuable if you have nested structures and arrays. – Barmar Jan 17 '18 at 21:22
  • 1
    @Barmar could you plese show en example of what an anonymous structure is? I was 100% sure this is what is called an anonymous struct... – LandonZeKepitelOfGreytBritn Jan 17 '18 at 21:22
  • 4
    Your code actually shows the difference between *initialization* and *assignment*, it is analogous to asking "why would I do `int x = 5;` instead of `int x; x = 5;` – M.M Jan 17 '18 at 21:23
  • maybe this will help: https://stackoverflow.com/questions/8932707/what-are-anonymous-structs-and-unions-useful-for-in-c11 – yano Jan 17 '18 at 21:33
  • Is the post about initialization vs. assignment or what is an anonymous `struct`? – chux - Reinstate Monica Jan 17 '18 at 21:34
  • 2
    Anonymous structures are very convenient when you have them nested into other structs/unions. This way you don't have to type the full "path" to the fields. – Eugene Sh. Jan 17 '18 at 21:37
  • I wonder how you ever obtained *the wrong idea*, and note that you seem to ask questions as I would consider prematurely... Could it be that the method you use to learn isn't working for you, and what you should actually be asking for is an "example" of a better method to learn? – autistic Jan 17 '18 at 22:43

4 Answers4

2

An anonymous struct is useful when you want to nest structures/unions without assigning a particular "meaning" to the inner structures. It lets you access the members of an inner structure as if they were a direct member of the enclosing struct. See the following example taken from cppreference.com:

Similar to union, an unnamed member of a struct whose type is a struct without name is known as anonymous struct. Every member of an anonymous struct is considered to be a member of the enclosing struct or union. This applies recursively if the enclosing struct or union is also anonymous.

struct v {
   union { // anonymous union
      struct { int i, j; }; // anonymous structure
      struct { long k, l; } w;
   };
   int m;
} v1;

v1.i = 2;   // valid
v1.k = 3;   // invalid: inner structure is not anonymous
v1.w.k = 5; // valid

The code you showed actually has nothing to do with anonymous structs. It is rather an example of using an initializer list with designated members.

Hope it helps :-)

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
1

Here's one use. When working with unions, it's implementation defined what you'll get when reading a union member that wasn't last written to. But, in the case of structures, you can inspect the common initial sequence of fields. Here's an example to illustrate:

#include <assert.h>

struct S1 {
  int  type;
  char value;
};

struct S2 {
  int   type;
  float value;
};

union U {
  struct S1 s1;
  struct S2 s2;
};

int main() {
  union U un;
  un.s1.type = 1;
  un.s1.value = 'c';
  assert(un.s2.type == 1);
}

As you can see above, it is guaranteed by the C standard that whatever I write to un.s1.type I can then read from un.s2.type. So far so good. But there's a problem if I try to do something like this instead:

union U {
  struct S1 s1;
  int type;
};

Now there is no guarantee. We can't read un.s1.type from un.type under the protection of the standard. But hope is not lost, we can just make it a field of a structure again, an anonymous structure, like so:

union U {
  struct S1 s1;
  struct {
    int type;
  };
};

The fields of an anonymous structure are "injected" into the enclosing structure or union, so we may refer to type by accessing un.type. And now were are back to the warm embrace of the standard. Since now we again have two structures with a common initial sequence of fields.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
1

Your example has nothing to do with anonymous structs, but only with initialization vs. assignement. It matters mainly when objects are declared const:

const  my_struct_t obj1 =
{
    .a = 33,
    .b = 44
};

is correct while this is not:

const my_struct_t obj2;
obj2.a = 55;   // error: try to assign to const object

Anonymous structures and unions allow members of a sub struct/union to be used as if they were members of the containing sub/union.

Draft n1570 for C11 says at 6.7.2.1 Structure and union specifiers §13 says:

An unnamed member whose type specifier is a structure specifier with no tag is called an anonymous structure; an unnamed member whose type specifier is a union specifier with no tag is called an anonymous union. The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.

and even gives a (non normative) example:

struct v {
    union { // anonymous union
        struct { int i, j; }; // anonymous structure
        struct { long k, l; } w;
    };
    int m;
} v1;
v1.i = 2; // valid
v1.k = 3; // invalid: inner structure is not anonymous
v1.w.k = 5; // valid
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

That's not an anonymous struct, that is simply using designated initializers, and you use them particularly when you don't need to provide values for all the members of a complicated struct.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23