You are on page 1of 4

Examples of Union in C - Stack Overflow Page 1 of 4

sign up log in tour help stack overflow careers

Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no
Take the 2-minute tour ×
registration required.

Examples of Union in C [closed]

I'm looking for some union examples, not to understand how union works, hopefully I do, but to see which kind of hack people do with
union.

So feel free to share your union hack (with some explanation of course :) )

c unions

edited Aug 14 '12 at 17:52 asked Apr 7 '09 at 8:15


timrau claf
13.2k 2 16 39 3,723 12 38 67

closed as not a real question by Ben D, Iswanto San, Oleksi, Matt, madth3 Mar 20 '13 at 1:12
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its
current form. For help clarifying this question so that it can be reopened, visit the help center.

If this question can be reworded to fit the rules in the help center, please edit the question.

8 Answers

One classic is to represent a value of "unknown" type, as in the core of a simplistic virtual
machine:

typedef enum { INTEGER, STRING, REAL, POINTER } Type;

typedef struct
{
Type type;
union {
int integer;
char *string;
float real;
void *pointer;
} x;
} Value;

Using this you can write code that handles "values" without knowing their exact type, for
instance implement a stack and so on.

Since this is in C, the inner union must be given a field name in the outer struct . In C++ you
can let the union be anonymous. Picking this name can be hard. I tend to go with something
single-lettered, since it is almost never referenced in isolation and thus it is always clear from
context what is going on.

Code to set a value to an integer might look like this:

Value value_new_integer(int v)
{
Value v;
v.type = INTEGER;
v.x.integer = v;
return v;
}

Here I use the fact that struct s can be returned directly, and treated almost like values of a
primitive type (you can assign struct s).

edited Apr 7 '09 at 8:32 answered Apr 7 '09 at 8:20


unwind
211k 31 288 409

I guess this one could be usefull! – claf Apr 7 '09 at 8:24

http://stackoverflow.com/questions/724617/examples-of-union-in-c 20/05/2015
Examples of Union in C - Stack Overflow Page 2 of 4

Here's a little one I use every day:

struct tagVARIANT {
union {
struct __tagVARIANT {
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union {
LONG lVal; /* VT_I4 */
BYTE bVal; /* VT_UI1 */
SHORT iVal; /* VT_I2 */
FLOAT fltVal; /* VT_R4 */
DOUBLE dblVal; /* VT_R8 */
VARIANT_BOOL boolVal; /* VT_BOOL */
_VARIANT_BOOL bool; /* (obsolete) */
SCODE scode; /* VT_ERROR */
CY cyVal; /* VT_CY */
DATE date; /* VT_DATE */
BSTR bstrVal; /* VT_BSTR */
IUnknown * punkVal; /* VT_UNKNOWN */
IDispatch * pdispVal; /* VT_DISPATCH */
SAFEARRAY * parray; /* VT_ARRAY */
BYTE * pbVal; /* VT_BYREF|VT_UI1 */
SHORT * piVal; /* VT_BYREF|VT_I2 */
LONG * plVal; /* VT_BYREF|VT_I4 */
FLOAT * pfltVal; /* VT_BYREF|VT_R4 */
DOUBLE * pdblVal; /* VT_BYREF|VT_R8 */
VARIANT_BOOL *pboolVal; /* VT_BYREF|VT_BOOL */
SCODE * pscode; /* VT_BYREF|VT_ERROR */
CY * pcyVal; /* VT_BYREF|VT_CY */
DATE * pdate; /* VT_BYREF|VT_DATE */
BSTR * pbstrVal; /* VT_BYREF|VT_BSTR */
IUnknown ** ppunkVal; /* VT_BYREF|VT_UNKNOWN */
IDispatch ** ppdispVal; /* VT_BYREF|VT_DISPATCH */
SAFEARRAY ** pparray; /* VT_BYREF|VT_ARRAY */
VARIANT * pvarVal; /* VT_BYREF|VT_VARIANT */
PVOID byref; /* Generic ByRef */
CHAR cVal; /* VT_I1 */
USHORT uiVal; /* VT_UI2 */
ULONG ulVal; /* VT_UI4 */
INT intVal; /* VT_INT */
UINT uintVal; /* VT_UINT */
DECIMAL * pdecVal; /* VT_BYREF|VT_DECIMAL */
CHAR * pcVal; /* VT_BYREF|VT_I1 */
USHORT * puiVal; /* VT_BYREF|VT_UI2 */
ULONG * pulVal; /* VT_BYREF|VT_UI4 */
INT * pintVal; /* VT_BYREF|VT_INT */
UINT * puintVal; /* VT_BYREF|VT_UINT */
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
};

This is the definition of the OLE automation variant data type. As you can see it has lots of
possible types. There are lots of rules around the types you can use in different situations,
depending on the capabilities of your intended client code. Not all types are supported by all
languages.

The types with VT_BYREF after them are used by languages such as VBScript that pass
parameters by reference by default. This means if you have some code that cares about the
variant structure details (such as C++) being called by code that doesn't (such as VB), then
you have to carefully dereference the variant parameter if required.

The byref types are also used to return values from functions. There is also support for array
types using the weirdly misnamed SAFEARRAY type - so difficult to use from C++.

If you have an array of strings, you can pass it to vbscript, but it cannot be used (except to print
the size). To actually read the values, the array data needs to be of type VT_BYREF | VT_BSTR .

edited Apr 7 '09 at 8:37 answered Apr 7 '09 at 8:19


1800 INFORMATION
63.5k 19 108 186

17 OMG, my eyes are bleeding! – paxdiablo Apr 7 '09 at 8:19

Where's the explanation? :-) – Paul Apr 7 '09 at 8:20

I thought it was self explanatory :) This is the definition of the OLE automation variant data type. As you
can see it has lots of possible types. Not all types are supported by all languages – 1800 INFORMATION
Apr 7 '09 at 8:22

http://stackoverflow.com/questions/724617/examples-of-union-in-c 20/05/2015
Examples of Union in C - Stack Overflow Page 3 of 4

The types with VT_BYREF after them are used by languages such as VBScript that pass parameters by
reference by default. There are lots of rules around the types you can use in different situations, depending
on the capabilities of your intended client code – 1800 INFORMATION Apr 7 '09 at 8:24

The byref types are also used to return values from functions. There is also support for array types using
the weirdly misnamed "SAFEARRAY" type - so difficult to use from C++ – 1800 INFORMATION Apr 7 '09
at 8:26

Unions are also commonly used in the lexical analysis and parsing stage of language
processors, like compilers and interpreters. Here is one I'm editing right now.

union {
char c;
int i;
string *s;
double d;
Expression *e;
ExpressionList *el;
fpos_t fp;
}

The union is used to associate semantic values with the tokens of the lexical analyzer and the
productions of the parser. This practice is quite common in grammar generators, like yacc,
which provides explicit support for it. The union can hold any of its values, but only one of them
at the time. For instance, at any one point from the input file you've either read a character
constant (stored in c ), or an integer (stored in i ) or a floating point number (stored in d ).
The grammar generator provides considerable assistance for determining which of the values
is stored at any one time depending on the rule being processed.

answered Apr 7 '09 at 8:26


Diomidis Spinellis
9,498 2 23 48

Please avoid "hacks" with union, they cause portability headaches (endianness, alignment
issues).

• A legitimate use of union is to store different data types at the same place, preferably with
a tag so that you know which type it is. See the example by 1800 INFORMATION.

• Don't use union to convert between data types, e.g. from an integer to several bytes. Use
shift and masking instead for portability.

answered Apr 7 '09 at 8:25


starblue
32.5k 8 52 104

Some union (see pthread.h on linux) helps portability don't you think so? – claf Apr 7 '09 at 8:27

1 There is no union in the pthread.h files on my system (all 48 of them). – starblue Apr 8 '09 at 18:48

look at the nptl source in glibc – claf Apr 17 '09 at 12:52

@claferri Please be more specific (which union in which file?). – starblue Apr 17 '09 at 14:59


struct InputEvent
{
enum EventType
{
EventKeyPressed,
EventKeyPressRepeated,
EventKeyReleased,
EventMousePressed,
EventMouseMoved,
EventMouseReleased
} Type;
union
{
unsigned int KeyCode;
struct
{
int x;
int y;
unsigned int ButtonCode;
};
};
};
...
std::vector<InputEvent> InputQueue;

with the union hack I can simply make a vector of objects. I'm sure this could be made more
clean...but it works for me - KISS

answered Apr 7 '09 at 8:22 

http://stackoverflow.com/questions/724617/examples-of-union-in-c 20/05/2015
Examples of Union in C - Stack Overflow Page 4 of 4

qwerty
248 1 6

SDL uses a similar event structure/union. – aib Apr 7 '09 at 8:39

We use unions for packed messages at work (C/C++), so we can pass around a structure with
an union as a data member, then access the the correct path based on id field in the structure.

Worked find until somebody wrote the structure to a file, now we are limited to the largest data
used in the file, because even thought there's a file version, nobody ever changed it....

So while useful for in-memory work, avoid blindly writing them to disk or network.

answered Apr 7 '09 at 9:26


Simeon Pilgrim
4,448 13 28

Coincidentally, I just used one in a Stackoverflow answer here so I could treat a word that was
made up of 6 bit fields as two 16 bit unsigned integers.

Years ago, I also used one for (the first) ARM C compiler - the instructions in those days were
all 32 bit, but had different layouts depending on the exact instruction. So I had a union to
represent an ARM instruction, containing a set of structs which each had the appropriate
bitfields for a specific instruction type.

answered Apr 7 '09 at 8:19


Paul
21.6k 11 61 101

The ARM thing look nice and ugly :) – claf Apr 7 '09 at 8:22

It was :) But (in a cautionary tale about portability of these things) it turned out I got all the bits in the wrong
order the first time around... – Paul Apr 7 '09 at 8:29

#define DWORD unsigned int


#define WORD unsigned short
#define BYTE unsigned char

typedef union _DWORD_PART_ {

DWORD dwWord;

struct {
WORD dwMSB;
WORD dwLSB;
}hw;

struct {

BYTE byMSB;
BYTE byMSBL;
BYTE byLSBH;
BYTE byLSB;

} b;

} DWORD_PART;

This is an easy way to access the words parts. (An once you are done, any change in
endianness of the platform can also be handled easily)

answered Apr 7 '09 at 8:26


Alphaneo
3,685 12 45 71

1 Note that this depends on implementation defined behavior. It is only portable to platforms where the
implementation defines that it will have the semantics you intend. It is legal for a platform to not overlap the
storage of the members of a union, for example, as long as it documented it. – RBerteig Apr 8 '09 at 2:21

1 I dont understand when you say this will not work. It works in Windows, Linux, ARM, MacOS, and PPC. Not
once I have seen it fail. Anyway, I thought this might be useful, if you dont want then SU. – Alphaneo Apr 8
'09 at 7:40

-1 This wrong for little endian machines (e.g. x86). Please don't use union for converting between machine
words and bytes, it is bad for portability. – starblue Mar 17 '14 at 11:19

http://stackoverflow.com/questions/724617/examples-of-union-in-c 20/05/2015

You might also like