Why are these restriction to union
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
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.
Having said that, unions only really make sense with PODs anyway. Everything else stems from that.
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).
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).
Quote:Original post by phresnelHmm, 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 :-)
Codeka: C++0x has unrestricted unions: n2544.pdf
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?).
Hmmm, minds of more flexible bitwise-memcpy come to mind ... all that in combination with better traits (is_pod<T> anyone?).
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.
Quote:Original post by Red AntQuote: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.
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};
Language lawyer alert:
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement