I've read that anonymous structs are a compiler extension and codeblocks allows them as long as -pedantic-errors are not enabled.

My question is, since it is not legal in C++, what would be the legal equivalent of:

typedef union XYZ
{
    int Color;
    struct
    {
        BYTE X, Y, Z;
    };
} *XYZ;

See if I name the struct i'd have to access it using it's name/object. If I switch the struct and the union, then the layout is completely different and as such changing one affects the other.

Also would #Pragma pack affect it?

Recommended Answers

All 3 Replies

AFAIK, there is no legal equivalent in C++. And any attempts to reproduce the same behavior could be very tricky (I can think of one, and it's not pretty).

What's wrong with access via the struct's name? It's not worth going through too much trouble just for a bit of syntactic sugar.

Also would #Pragma pack affect it?

Huuu.?..?..

Ahh well i was thinking that if I pass the struct to something like CreateDIBitmaps or if I pass it as a pointer, it won't fill in the Inner struct with values. Correct?

My XYZ and RGB structs are the same so I'll use RGB as an example:

typedef union RGB
{
    uint32 Color;
    struct Inner   //Named struct
    {
        unsigned char B, G, R, A;
    };
} *PRGB;

Now if the struct is un-named, it will fill in all the values right?
I can do RGB P = {16777215}; and R, G, B gets filled with 255, 255, 255, 0.

When I name my struct "Inner" it does not happen unless I access those values specifically through the name or an object of that struct.

I asked about the #Pragma pack because I learned from researching online that it will keep the alignment the same and that I can change the alignment. So I thought that by putting it, I can change an anonymous union to the same as a struct without a name? That way both will have the same alignment no?

My Idea:

typedef struct XYZ //Somehow turn this into a union with pragma pack?
{
    uint32_t Color;
    union          //Somehow turn this into a struct
    {
        uchar X, Y, Z;
    };
} *pXYZ;

I was trying to think of a way to make it legal all day but I can't come up with anything. And if I switch union with struct and vice-versa, I get an all black bitmap. Leaving the struct unnamed, I get a nice colourful bitmap (exactly what I want). But Anonymous structs aren't legal :S

struct Inner //Named struct

That's not a named struct, that's a nested struct type declaration. As in:

// this declares a struct type called Foo:
struct Foo {
  //.. 
};

// this declares a variable called 'foo' of an unnamed type:
struct {
  //..
} foo;

// this declares both a struct-type called Bar and an object 'bar' of that type:
struct Bar {
  //..
} bar;

Inside a union declaration, it is the same logic. In your example, you have declared a struct-type, nested in the union declaration, accessible as the type RGB::Inner. The point is that it is a type declaration, not a data member of the union. The thing that C++ does not allow is this:

struct {
  //..
};

Because it is neither a class declaration or an object declaration (of unnamed class). Some extensions (in gcc, for example) allow the above within a another class/struct or union declaration, and it is treated as the declaration of an anonymous object of an unnamed class/struct.

The legal way to declare your RGB union is as follows:

typedef union RGB
{
    uint32 Color;
    struct
    {
        unsigned char B, G, R, A;
    } Channels;
} *PRGB;

Now, when you initialize an object as RGB P = {16777215}, it will also fill the channel values, accessible through P.Channels.R, P.Channels.G, P.Channels.B, P.Channels.A. So, that's what I meant when I said that it is only syntactic sugar to have an anonymous struct in your union. The only difference is between accessing the R,G,B,A elements as above or with P.R, P.G, P.B, P.A.

Somehow turn this into a union with pragma pack?

No. The pack pragma (which isn't standard either, of course) is not for that purpose at all. Here is the purpose of that pragma option. If you have a struct like this:

struct Foo {
  char c;
  int i;
};

Then, you will find that sizeof(Foo) != sizeof(char) + sizeof(int) because the compiler will arrange the bytes such that the data members are aligned with the system's alignment size (usually 4 bytes, sometimes 8). In this case, it will probably lead to sizeof(Foo) == 8 or so. So, you get 1 byte for the char, then 3 bytes of padding (empty), and 4 bytes for the integer. Now, by using the #pragma pack(1), you tell the compiler to align things to 1 byte intervals, probably resulting in sizeof(Foo) == 5. But, certainly, it does not turn a struct into a union.

commented: :o Thank you lots! Time to go learn why it pads. +5
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.