Sign in to follow this  
Padala Srikant

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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by phresnel
Codeka: 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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Codeka
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 :-)


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



Share this post


Link to post
Share on other sites
Quote:
Original post by Red Ant
Quote:
Original post by Codeka
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 :-)


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 this post


Link to post
Share on other sites
Quote:
Original post by direwulf
2) 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 this post


Link to post
Share on other sites
Language lawyer alert:
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.

Share this post


Link to post
Share on other sites

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

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this