Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Union – useless anachronism or useful old school trick?

I recently came across a great data structures book,"Data Structures Using C" (c) 1991, at a local Library book sale for only $2. As the book's title implies, the book covers data structures using the C programming language.

I got the book knowing it would be out-dated but would probably contain lots of advanced C topics that I wouldn't encounter elsewhere.

Sure enough within 5 minutes I found something I didn't know about C. I came across a section talking about the union keyword and I realized that I had never used it, nor ever seen any code that does. I was grateful for learning something interesting and quickly bought the book.

For those of you not knowledgeable about what a union is, the book uses a good metaphor to explain:

To fully understand the concept of a union, it is necessary to examine its implementation. A Structure may be regarded as a road map to an area of memory. It defines how the memory is to be interpreted. A union provides several different road maps for the same area of memory, and it is the responsibility of the programmer to determine which road map is in current use. In practice, the compiler allocates sufficient storage to contain the largest member of the union. It is the road map, however, that determines how that storage is to be interpreted.

I could easily come up with contrived situations or hacks where I would use a Union. (But I am not interested in contrived situations or hacks...)

Have you used or seen an implementation where using Union solved the problem **more elegantly** than not using a Union?

Added bonus if you include a quick explanation of why using union was better/easier than not using a union.

like image 651
Trevor Boyd Smith Avatar asked May 13 '09 13:05

Trevor Boyd Smith


3 Answers

UNIONs implement some sort of polymorphism in a non-OOP world. Usually, you have a part which is common and depending on that part, you use the rest of the UNIONs. Therefore, in such cases where you do not have an OOP language and you want to avoid excessive pointer arithmetic, unions can be more elegant in some cases.

like image 192
Lucero Avatar answered Nov 15 '22 10:11

Lucero


It's useful for setting bits in, say, registers instead of shift/mask operations:

typedef union {
    unsigned int as_int; // Assume this is 32-bits
    struct {
        unsigned int unused1 : 4;
        unsigned int foo : 4;
        unsigned int bar : 6;
        unsigned int unused2 : 2;
        unsigned int baz : 3;
        unsigned int unused3 : 1;
        unsigned int quux : 12;
    } field;
} some_reg;

Note: Which way the packing happens is machine-dependent.

some_reg reg;
reg.field.foo = 0xA;
reg.field.baz = 0x5;
write_some_register(some_address, reg.as_int);

I might have blown some syntax somewhere in there, my C is rusty :)

EDIT:

Incidentally, this works the opposite way also:

reg.as_int = read_some_register(some_address);
if(reg.field.bar == BAR_ERROR1) { ...
like image 39
scottfrazer Avatar answered Nov 15 '22 08:11

scottfrazer


Indeed, it's a great tool when you write things like device drivers (a struct that you want to send to device that can have several similar but different formats) and you require precise memory arrangement...

like image 10
mmx Avatar answered Nov 15 '22 10:11

mmx