Search code examples
cstructdeclaration

What is the difference between a struct in a struct, and a named anonymous struct that is part of a surrounding struct?


Example:

#include <stdio.h>

struct not_inner {
    int a;
    int b;
};

struct outer {
    struct {
        int a;
        int b;
    } x;
    
    struct not_inner y;
};

int main()
{
    struct outer O = {1, 2, 3, 4};
    //x.a = 5;
    

    printf("%d %d %d %d", O.x.a, O.x.b, O.y.a, O.y.b);

    return 0;
}

Mainly, I am intersted in what is the difference between x and y regarding:

  • the c99 standard
  • access speed
  • scope

Solution

  • What is the difference between a struct in a struct, and a named anonymous struct that is part of a surrounding struct?

    "[N]amed anonymous struct" is a curious turn of phrase, but I take you to mean member x of struct outer. I would call that a member whose type is an untagged structure type. It is definitely not an anonymous struct -- that has a specific, more natural meaning, and a different significance.

    Mainly, I am intersted in what is the difference between x and y regarding:

    • the c99 standard

    Both forms are equally conformant to C99 and all subsequent versions of C.

    • access speed

    There is no reason to expect any difference in access speed arising from whether a structure type is tagged. The structure tag has no runtime representation.

    • scope

    Unless it has a typedef alias, an untagged structure type cannot be referenced outside the declaration in which it appears. But that does not impair access to any objects declared with that type, nor to their members, nor does it prevent compatible types being declared. You can do anything with your outer.x that you can do with your outer.y, but some things you might want to do would require more code for x.

    Note well that the specific form you present for x is a bit unusual (albeit certainly not unknown), but variations along these lines are relatively common:

    typedef struct {
        int a;
        int b;
    } untagged_struct;
    
    struct outer2 {
        untagged_struct x;
        
        struct not_inner y;
    };
    

    The type of outer2.x is also an untagged structure type. Having a typedef alias for that type solves substantially all of the issues that might make some operations on outer.x require more code than similar operations on outer.y.

    As a matter of style, however, I personally prefer to avoid most uses of typedef, including in particular for structure types. I would rather write (and see) struct my_struct than just my_struct or the like.