Unions

Feb 5, 2013 at 6:23pm
closed account (LN7oGNh0)
Ive looked at the tutorial and Im not getting what unions ares used for. Why are they associated a lot with typedefs and what do they do that structs cant?

Thanks.
Feb 5, 2013 at 6:45pm
Unions are very seldomly useful in C++. They're for conserving space if you have multiple different types of data in a single type... but are only going to use one type at a time.

Unions differ from structs because each member of a struct is stored independently and can retain its own value. IE:

1
2
3
4
5
struct foo
{
  int a;
  int b;
};


Here, 'a' and 'b' are two separate variables. Both can keep track of a value independently of another.

However that is not true of a union:

1
2
3
4
5
union foo
{
  int a;
  int b;
};


Here, 'a' and 'b' [possibly] share memory space, and therefore you can only use one of them at a time. As soon as you write to 'a', the contents of 'b' become undefined. Likewise, writing to 'b' will invalidate/destroy any contents that are in 'a'.


The perk is that unions [potentially] take up less memory, because they only need to reserve space for their largest member, whereas structs need to reserve space for the sum of all their members.

About the only time I've ever seen unions be used effectively is in libs like SDL's event system. Where they have a struct for each kind of event:

1
2
3
4
5
6
7
8
9
10
11
struct SDL_Event
{
  int type;  // something to tell you what kind of event this is
  union
  {
    SDL_KeyEvent  key;  // event data for keyboard
    SDL_MouseEvent mouse;  // event data for mouse
    SDL_SizeEvent size;  // event data for window resizing
    // ... etc
  };
};


This works because you only need one of those event types at a time. Which type you have depends on the 'type' variable.


However... SDL is a C lib. And in C++ there are much safer ways to approach this same problem using inheritance and other techniques.


So really... unions are not that useful in C++.
Feb 5, 2013 at 9:31pm
closed account (LN7oGNh0)
thank you.
Feb 5, 2013 at 9:42pm
They can be crudely used for serialisation in sending data over sockets, too.

Obviously, I'd only advise this on small-scale, personal projects. Nothing enterprise. ;-)
Last edited on Feb 5, 2013 at 9:42pm
Feb 6, 2013 at 12:46am
Unions can be useful when dealing with hardware representations, but are also a common source of portability issues, particularly between machines with different architectures. Consider the following simple example:

1
2
3
4
union foo
{  short a;
    char b[2];
};


If I store a number into a, then refer to b[0], am I referring to the most significant byte, or the least significant byte of a? The answer depends on the hardware architecture. So I may get different results depending on the machine the program is running on.
Feb 6, 2013 at 7:45pm
closed account (LN7oGNh0)
Thank you again.
Feb 6, 2013 at 7:58pm
AbstractionAnon wrote:
If I store a number into a, then refer to b[0], am I referring to the most significant byte, or the least significant byte of a?


Neither. You're actually doing undefined behavior. Unions should not be used that way.
Feb 7, 2013 at 12:52am
@disch - That was the point of my example. I was trying to show why it was bad practice.

However, i disagree with "neither". b[0] or b[1] willreturn something. Just don't count on it to be portable.
Feb 7, 2013 at 12:59am
It will certainly return something, but according to the standard it is undefined. A conforming implementation is free to have that return any arbitrary value, not necessarily the MSB or LSB.
Feb 7, 2013 at 5:14am
However, i disagree with "neither". b[0] or b[1] willreturn something. Just don't count on it to be portable.


It's not just nonportable... it's undefined. Undefined is undefined -- you can't count on it being anything.
Feb 7, 2013 at 8:41am
Basically I would go with the principal that Unions are outdated, they were created to save space way back when 100kb was a large amount of memory. It's good to know they are there, and it's cool if you can find a use for them, but otherwise just ignore it and move on to bigger and better things.
Topic archived. No new replies allowed.