skip to Main Content

I have a union with a struct inside. When trying to compile on Linux, I get an error (or more like 50 of the same kind). The same code works in Visual Studio on Windows.

main.c:772:43: error: ‘union data’ has no member named ‘B’
fwrite(&u.B, sizeof(char), sizeof(u.B), out);
^

I declare all my structs in a header file, "typedefs.h":

union data {
    short buf;
    struct D {
        char A;
        char B;
    };
};

What could be the issue and possible fix?

2

Answers


  1. You’ve declared a struct type inside of a union, but not an instance of a struct. If you remove the tag name from the struct, you’ll define an instance of an anonymous struct inside of the union. This will also make the struct members look like members of the union.

    union data {
        short buf;
        struct {
            char A;
            char B;
        };
    };
    
    Login or Signup to reply.
  2. Anonymous structures are allowed as nested members of other structures or unions in Standard C but they can’t have a tag. From this Draft C11 Standard:

    6.7.2.1 Structure and union specifiers


    13     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.

    However, in your code, although the nested structure doesn’t have a name, it does have a tag (the D); so, in formal terms, it cannot be used as an anonymous structure and must be given a name. From the same section of the Standard cited above:

    2    A struct-declaration that does not declare an anonymous
    structure or anonymous union shall contain a struct-declarator-list.

    However, the MSVC (Visual Studio) compiler accepts unnamed (‘anonymous’) structures that have a tag, as an extension.

    So, to use the code in your write call as-is, and to keep it Standard-conformant, you need to remove the D tag from your inner structure:

    union data {
        short buf;
        struct {
            char A;
            char B;
        };
    };
    

    Note that the clang-cl compiler (a version of clang that can be used within Visual Studio) gives a warning for your version of the code (though not especially helpful unless you can parse the final, [-Wmicrosoft-anon-tag] part):

    warning : anonymous structs are a Microsoft extension
    [-Wmicrosoft-anon-tag]

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search