6.3. UnionsThis is a printer-friendly version of a page on the GBdirect web site. The original page may be found at https://publications.gbdirect.co.uk/c_book/chapter6/unions.html. Unions don't take long to explain. They are the same as structures, except
that, where you would have written #include <stdio.h> #include <stdlib.h> main(){ union { float u_f; int u_i; }var; var.u_f = 23.5; printf("value is %f\n", var.u_f); var.u_i = 5; printf("value is %d\n", var.u_i); exit(EXIT_SUCCESS); }Example 6.11 If the example had, say, put a The C compiler does no more than work out what the biggest member in a union can be and allocates enough storage (appropriately aligned if neccessary). In particular, no checking is done to make sure that the right sort of use is made of the members. That is your task, and you'll soon find out if you get it wrong. The members of a union all start at the same address—there is guaranteed to be no padding in front of any of them. The most common way of remembering what is in a union is to embed it in a structure, with another member of the structure used to indicate the type of thing currently in the union. Here is how it might be used: #include <stdio.h> #include <stdlib.h> /* code for types in union */ #define FLOAT_TYPE 1 #define CHAR_TYPE 2 #define INT_TYPE 3 struct var_type{ int type_in_union; union{ float un_float; char un_char; int un_int; }vt_un; }var_type; void print_vt(void){ switch(var_type.type_in_union){ default: printf("Unknown type in union\n"); break; case FLOAT_TYPE: printf("%f\n", var_type.vt_un.un_float); break; case CHAR_TYPE: printf("%c\n", var_type.vt_un.un_char); break; case INT_TYPE: printf("%d\n", var_type.vt_un.un_int); break; } } main(){ var_type.type_in_union = FLOAT_TYPE; var_type.vt_un.un_float = 3.5; print_vt(); var_type.type_in_union = CHAR_TYPE; var_type.vt_un.un_char = 'a'; print_vt(); exit(EXIT_SUCCESS); }Example 6.12 That also demonstrates how the dot notation is used to access structures
or unions inside other structures or unions. Some current C compilers allow
you to miss bits out of the names of embedded objects provided that they are
not ambiguous. In the example, such an unambiguous name would be
It is because of unions that structures cannot be compared for equality. The possibility that a structure might contain a union makes it hard to compare such structures; the compiler can't tell what the union currently contains and so wouldn't know how to compare the structures. This sounds a bit hard to swallow and isn't 100% true—most structures don't contain unions—but there is also a philosophical issue at stake about just what is meant by ‘equality’ when applied to structures. Anyhow, the union business gives the Standard a good excuse to avoid the issue by not supporting structure comparison. Previous section [https://publications.gbdirect.co.uk/c_book/chapter6/structures.html] | Chapter contents [https://publications.gbdirect.co.uk/c_book/chapter6/] | Next section [https://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html] |