开发者

Usage of union inside a class

I saw some code as follows:

class A 
{
private:
    union {
        B *rep;
        A *next;
    }; // no variables of this anonymous defined!

    void func()
    {
        A *p = new A;

        p->next = NULL; // why p has a member variable of 'next'?
    }
};

I have compiled the above cod开发者_如何学Pythone with VS2010 without any error. Here is the question,

why p has member variable 'next'?

    union {
        B *rep;
        A *next;
    };

As far as I know, this is an anonymous union without even defining a variable. How can we access the member variables inside this union like that?


Because that's pretty much what an anonymous union does, it defines zero-or-more variables in the enclosing namespace (which in a class declaration makes them field names) which occupy overlapping memory. Hence in use it's the same as if you'd declared

class A 
{
private:
    B *rep;
    A *next;

    void func()
    {
        A *p = new A;

        p->next = NULL;
    }
};

...except for rep and next occupying overlapping space (or given that the two pointers will have the same size, the same space), and hence all the dangers and benefits that come with a named union.


Here's the quote from the standard that controls this behavior: section [class.union] (wording from C++0x draft n3242)

A union of the form union { member-specification } ; is called an anonymous union; it defines an unnamed object of unnamed type. The member-specification of an anonymous union shall only define non-static data members. [ Note: Nested types and functions cannot be declared within an anonymous union. — end note ] The names of the members of an anonymous union shall be distinct from the names of any other entity in the scope in which the anonymous union is declared. For the purpose of name lookup, after the anonymous union definition, the members of the anonymous union are considered to have been defined in the scope in which the anonymous union is declared.


I am not really sure I understand your question.

A has the member p, because you declared it in A inside an anonymous union along with rep.

You did declare a variable! It's just that 'rep' and 'next' share the same memory.

You can access it just the way you did.

anonymous unions (just like structs) put their members in the same namespace as the above namespace is.

It's useful for e.g.:

union W00t {
    struct {
         uint32_t a,b;
    };
    struct {
         uint64_t c;
    };
 }


I'm surprised there is a modern compiler which still allows that construct. It is one from the early days of C, circa 1975. In those days, structure and union members were not actually tied to a particular structure, but contained as attributes an offset from a base address and a data type.

The end result was that using a structure or union properly results in correct code with expressions evaluated as expected. The only difference is that misuse of a structure member with a pointer unassociated with the type would not be flagged as an error. I don't think there was any particular reason for not enforcing the associate—K&R hint that future compilers hopefully would check such uses—probably just to save symbol table space in 16-bit land.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜