Jump to content
  • Advertisement
Sign in to follow this  
Noir

unions

This topic is 4871 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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];
};

Share this post


Link to post
Share on other sites
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;
};

Share this post


Link to post
Share on other sites
That's precisely the point. It is for convenience. You can do "allbytes = (allbytes & 0xFF00FFFF) | (0x12 << 16);" or "byte3 = 0x12", for instance.

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
Thanks, I see I probably won't be using it much then...until I really know what I'm doing anyways.

Share this post


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

Share this post


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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!