cstructsyntaxunions

What is the right syntax for declaring members that are struct or union?


Long story short, I generate headers out of a Sony PlayStation .SYM symbol file.

While I test the validity of the syntax with Visual Studio Code, I get the following:

tag kind of union is incompatible with declaration of class "PacketData"

Example:

struct PacketData
{
    short Data[2];
    unsigned long Control;
};

struct Packet
{
    unsigned char CheckSum;
    char Action;
    short Padw;
    union PacketData Data; // tag kind of union is incompatible with declaration of class "PacketData"
};

That problem appears to be solvable by removing union before PacketData.

This is the struct as outputted by DUMPSYM.EXE command-line utility:

The struct:

02cc47: $00000000 94 Def class STRTAG type STRUCT size 8 name Packet
02cc5b: $00000000 94 Def class MOS type UCHAR size 0 name CheckSum
02cc71: $00000001 94 Def class MOS type CHAR size 0 name Action
02cc85: $00000002 94 Def class MOS type SHORT size 0 name Padw
02cc97: $00000004 96 Def2 class MOS type UNION size 4 dims 0 tag PacketData name Data
02ccb6: $00000008 96 Def2 class EOS type NULL size 8 dims 0 tag Packet name .eos

The union:

02cbe2: $00000000 94 Def class UNTAG type UNION size 4 name PacketData
02cbfa: $00000000 96 Def2 class MOU type ARY SHORT size 4 dims 1 2 tag  name Data
02cc13: $00000000 94 Def class MOU type ULONG size 0 name Control
02cc28: $00000004 96 Def2 class EOS type NULL size 4 dims 0 tag PacketData name .eos

However, why do members that are structs can optionally have the struct prefix?

struct Sprite
{
    unsigned char X;
    unsigned char Y;
    unsigned short Page;
    unsigned char SWidth;
    unsigned char SHeight;
    unsigned short Clut;
};

struct SpriteData
{
    struct Sprite *Sprites;
    struct Sprite *EndSprites;
    unsigned long Data;
};

Can you clarify on how one shall declare such members?


Solution

  • You've defined struct PacketData, and later tried to create a variable/member of type union PacketData. These are two different types.

    The specific error message you're getting suggests that you're compiling with a C++ compiler. In C++, you can create an instance of a struct or union without using the corresponding keyword. This also means that in C++, you can't create a struct and a union with the same name, which is what the error message is telling you.

    Given that the dump you've posted is telling you that PacketData is a union, you should define it as that type:

    union PacketData
    {
        short Data[2];
        unsigned long Control;
    };
    

    And if your code is in fact C, you should be compiling with a C compiler. If this happens to be MSVC, that means your source file needs to have a .c extension.