Unions

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.
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++.
closed account (LN7oGNh0)
thank you.
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
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.
closed account (LN7oGNh0)
Thank you again.
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.
@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.
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.
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.
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.