# Why are these restriction to union

## Recommended Posts

please explain with examples why these restriction are there in union 1.No static variables can be members of a union. 2.A reference member cannot be used 3.A union cannot have as a member any object that overloads the = operator 4.no object can be a member of a union if the object has an explicit constructor or destructor function. 5.unions cannot be involved in inheritance

##### Share on other sites
We don't typically like answering homework questions here.

Having said that, unions only really make sense with PODs anyway. Everything else stems from that.

##### Share on other sites
Dura lex sed lex.

Codeka: C++0x has unrestricted unions: n2544.pdf (this might also be useful for the OP's homework). In the end, pod or non-pod, everything is bits and bytes (or let's concentrate on the byte, which is the smallest common denominator in C++), and unions are anyways not for everyday use and for careful programmers only, so restrictions towards POD-types always seemed unnatural to me (imho, it doesn't make less sense than with restricted unions).

##### Share on other sites
Quote:
 Original post by phresnelCodeka: C++0x has unrestricted unions: n2544.pdf
Hmm, didn't know that. Personally, I think they should stay the way they are - that proposal looks like pretty scary to me - but I'm not a language designer :-)

##### Share on other sites
They could be really useful e.g. to write variants of non-pod types, which is something I could really need. And imagine how nice you could define a generic variant type using variadic templates, yay. Also note that with the relaxation of POD rules, some more types considered non-POD so far will now qualify as a POD.

Hmmm, minds of more flexible bitwise-memcpy come to mind ... all that in combination with better traits (is_pod<T> anyone?).

##### Share on other sites
Quote:
 Original post by CodekaHmm, didn't know that. Personally, I think they should stay the way they are - that proposal looks like pretty scary to me - but I'm not a language designer :-)

Personally I wonder what unions are good for anyway. :p I've never ever felt the need to use a union anywhere.

##### Share on other sites
Quote:
Original post by Red Ant
Quote:
 Original post by CodekaHmm, didn't know that. Personally, I think they should stay the way they are - that proposal looks like pretty scary to me - but I'm not a language designer :-)

Personally I wonder what unions are good for anyway. :p I've never ever felt the need to use a union anywhere.

There are 4 basic uses of unions I'm aware of.

1) When you need to keep a class size small to optimize cache coherency, you may find that two data members are only used in a mutually exclusive context. In this case using a union provides a simple and intuitive syntax for accessing these two separate variables without bloating the class, and without the need for ugly bit hacks.

2) They are sometimes used essentially as a replacement reinterpret_cast, although I believe this may technically be bad behavior.

3) They provide a convenient syntax for accessing the same variable by two different names, which is useful in some contexts.

4) Although anonymous unions are supported by ISO C++, anonymous structs are not. Nevertheless, most compilers have extensions that allow anonymous structs, and the combination of both allows you to do magic like this:

struct vector4{  union {    float data[4];    struct {       float x,y,z,w;    };  };};vector4 v = {{1,2,3,4}};assert( v[0] == v.x );

unions can be significantly more general than this, having their own constructors, destructors, member functions...although I'm not aware of any reasons to use those features.

##### Share on other sites
Quote:
 Original post by direwulf2) They are sometimes used essentially as a replacement reinterpret_cast, although I believe this may technically be bad behavior.

In that context, afaik, they are the only sanctioned way to do type-punning (without aliasing issues).

int x;float y = *reinterpret_cast<float*>(&x); // obvious aliasing

int x;float y = reinterpret_cast<float&>(x); // less obvious aliasing

int x;float y = *(float*)&x; // same as first

Instead, either rethink your algorithm, or use an union:

 int x;union { int as_int; float as_float } const punned = {x};

##### Share on other sites
Quote:
 In that context, afaik, they are the only sanctioned way to do type-punning (without aliasing issues).

C99's J.1 says "The value of a union member other than the last one stored into [is unspecified]". There are two aliasing-proof and sanctioned ways to perform type punning:
- assemble the desired type by loading char values and shifting them according to the processor's byte order;
- use memcpy(). This communicates the intent clearly and avoids any runtime penalty (ICC11 is studly enough to replace it with a sequence of move instructions).
That said, union_cast is explicitly allowed by GCC because it is so widespread.

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

• ### Forum Statistics

• Total Topics
628314
• Total Posts
2982021

• 9
• 9
• 13
• 11
• 14