unions

Started by
13 comments, last by doynax 19 years, 2 months ago
I understand that unions are kind of like structs but the members share the same memory. What I don't understand is the practicality of unions. What is their use? For example, when would I be concerned with accessing information like this:


#include <iostream>
using namespace std;

union MyUnion
{
	long allbytes;
	struct tagpart
	{
		char byte1;
		char byte2;
		char byte3;
		char byte4;
	}part;
};

int main(int argc, int argv[])
{
	MyUnion m;
	m.part.byte1 = 'a';
	m.part.byte2 = 'b';
	m.part.byte3 = 'c';
	m.part.byte4 = 'd';
	cout << m.allbytes << "\n";
	cout << m.part.byte1 << "\n";
	cout << m.part.byte2 << "\n";
	cout << m.part.byte3 << "\n";
	cout << m.part.byte4 << "\n";
	return 0;
}


Whenever I change one member of the union, all members change and I just don't see the reasoning for including this functionality in C/C++. Its probably simple and I'm just too n00b to see it. =P
The man within the man. The love within the love. The sin within the sin.
Advertisement
Say you have a matrix structure you could use a union to give two different ways to access it. You can access it via ._11 or via m_indices[0][0].

	union	{		struct 		{			float	_11, _12, _13, _14,					_21, _22, _23, _24,					_31, _32, _33, _34,					_41, _42, _43, _44;		};		float m_indices[4][4];	};
Unions has two primary uses.

1. Variants, store different kinds of data in the same structure depending on it's state.
struct variant { enum {  CHAR,  INTEGER  FLOAT,  DOUBLE,  POINTER } type; union {  char c;  int i;  float f;  double d;  void *p; } data;};
2. Accessing the same data in different ways depending on the context.
union pixel { u32 packed; struct {  u8 r, g, b, a; } components;};
That's precisely the point. It is for convenience. You can do "allbytes = (allbytes & 0xFF00FFFF) | (0x12 << 16);" or "byte3 = 0x12", for instance.
Kippesoep
or my fav:

union color{    int value;    struct    {        byte red;        byte green;        byte blue;        byte alpha;    };};


(Haven't used a union or an annon struct in a looong time, that syntax might be a bit off)
wow, those replies poored in faster than I could type mine...
Well, for example you could use it in a vector class...
That way you could both have access to the vector in array form, and as xyz form..
class CMyVec{public:   union   {      float arr[3];      float x,y,z;   };};


It was some time since i looked at unions, so pardon me if the code isn't correct...it should be enough to show one area of usage though.

EDIT: Argh, heavily beaten [grin]
----------------------------------------------------------------------------------------------------------------------"Ask not what humanity can do for you, ask what you can do for humanity." - By: Richard D. Colbert Jr.
Thanks, I see I probably won't be using it much then...until I really know what I'm doing anyways.
The man within the man. The love within the love. The sin within the sin.
a union can still exist to offer most of the struct functionality, constructor/destructor methods, static members... etc...

take a look at the following example:
#include <iostream>union error	{	int i;	struct		{		unsigned short   code;		unsigned         priority : 2;	// 00 is normal, 01 is low, 10 is high, 11 is extreme...		unsigned         warning  : 1;	// 1 means this is just a warning, not a real error...		};	static int ii;	// errors counter	error(int _i = 0): i(_i) { ii++; }	operator int() { return this->i; }	bool is_warning() { if( this->priority ) return true; return false; }	static error system_error(){ error r; r.code = 10; r.priority = 0x2; return r; }	};int error::ii = 0;int main()	{	error e;	e.i = 5;		// wil affect everything...	e.code = 10;	// wont affect other things...	e.is_warning();	// will return the warning state :)	std::cout << (int)e << std::endl;	std::cout << (int)error::system_error() << std::endl;	std::cout << error::ii << std::endl;	}



/widen your imagination.
Unions are used when a data structure might contain distinct, but mutually-exclusive, pieces of data, and you want to make efficient use of the space. So you would have a union member in your data structure, along with a tag indicating which 'version' of the union you are actually using.

Their usage as an utter subversion of C's already ailing type system (what most of the other posters have demonstrated) is completely incidental and absolutely non-portable. You should only consider that one union member is valid at any given time.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan

This topic is closed to new replies.

Advertisement