Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

C Language Dictionary

  1. Home
  2. C Language Dictionary
  3. union

union

A data structure in which multiple members share the same memory region. It is used to interpret the same data as different types, or to reduce memory usage. The size of a union equals the size of its largest member.

Syntax

union UnionTagName {
    type memberName1;
    type memberName2;
};

// Declare a union variable.
union UnionTagName variableName;

// Access a member (same notation as struct).
variableName.memberName;
pointer->memberName;

// Initialization can only target the first member (C89).
// C99 and later allow designated initializers.
union UnionTagName variableName = {.memberName = value};

union vs. struct

Itemstructunion
MemoryAllocates the total size of all members (plus padding).Allocates only enough space for the largest member.
AccessAll members can be accessed independently.Only the last written member holds a valid value.
Use caseUsed to group multiple pieces of data together.Used to interpret the same memory as different types.

Sample Code

sample_union.c
#include <stdio.h>
#include <stdint.h>

/* A union that interprets a number as different types. */
union Number {
    int i;
    float f;
    unsigned char bytes[4];
};

/* Tagged union: tracks which member is active using an enum. */
typedef enum { TYPE_INT, TYPE_DOUBLE, TYPE_STRING } ValueType;

typedef struct {
    ValueType type;
    union {
        int i_val;
        double d_val;
        char s_val[64];
    } data;
} Value;

void print_value(const Value *v) {
    switch (v->type) {
        case TYPE_INT:    printf("int: %d\n", v->data.i_val);    break;
        case TYPE_DOUBLE: printf("double: %f\n", v->data.d_val); break;
        case TYPE_STRING: printf("string: %s\n", v->data.s_val); break;
    }
}

int main(void) {
    union Number n;

    n.i = 42;
    printf("int value: %d\n", n.i);

    /* Writing as float invalidates the int member. */
    n.f = 3.14f;
    printf("float value: %f\n", n.f);

    /* Check endianness via bytes member. */
    n.i = 1;
    printf("bytes[0] = %u\n", n.bytes[0]); /* 1 on a little-endian system */

    printf("Size of union Number: %zu bytes\n", sizeof(union Number));

    /* Tagged union for variant data. */
    Value v1 = {TYPE_INT, {.i_val = 100}};
    Value v2 = {TYPE_DOUBLE, {.d_val = 3.14}};
    print_value(&v1);
    print_value(&v2);

    return 0;
}

Run the following command:

gcc union.c -o union
./union
int value: 42
float value: 3.140000
bytes[0] = 1
Size of union Number: 4 bytes
int: 100
double: 3.140000

Checking Endianness

A union lets you inspect the byte order (endianness) of an integer value — a technique commonly used in embedded and network programming.

union_endian.c
#include <stdio.h>
#include <stdint.h>

union Endian {
    uint32_t value;
    unsigned char bytes[4];
};

int main(void) {
    union Endian e;
    e.value = 0x01020304;

    printf("value = 0x%08X\n", e.value);
    printf("bytes: [0]=%02X [1]=%02X [2]=%02X [3]=%02X\n",
           e.bytes[0], e.bytes[1], e.bytes[2], e.bytes[3]);

    if (e.bytes[0] == 0x04) {
        printf("Little-endian (least significant byte first)\n");
    } else {
        printf("Big-endian (most significant byte first)\n");
    }

    /* View the bit pattern of a float as uint32_t. */
    union { float f; uint32_t u; } fu;
    fu.f = 1.0f;
    printf("Bit pattern of 1.0f: 0x%08X\n", fu.u);

    return 0;
}

Run the following command:

gcc union_endian.c -o union_endian
./union_endian
value = 0x01020304
bytes: [0]=04 [1]=03 [2]=02 [3]=01
Little-endian (least significant byte first)
Bit pattern of 1.0f: 0x3F800000

Common Mistakes

Common Mistake: Reading a Member That Was Not Written

In a union, only the last-written member holds a valid value. Reading a different member is undefined behavior (except via an unsigned char array).

union_undef_ng.c
#include <stdio.h>

union Data {
    int i;
    float f;
};

int main(void) {
    union Data d;

    /* NG: writing float then reading int is undefined behavior */
    d.f = 3.14f;
    /* printf("%d\n", d.i); */ /* undefined behavior */

    /* OK: read only the member you wrote */
    d.i = 42;
    printf("int: %d\n", d.i); /* OK: wrote i, read i */

    d.f = 2.71f;
    printf("float: %f\n", d.f); /* OK: wrote f, read f */

    return 0;
}

Run the following command:

gcc union_undef_ng.c -o union_undef_ng
./union_undef_ng
int: 42
float: 2.710000

Overview

The defining characteristic of a union is that all its members share the same memory address, allowing a single variable to be interpreted as multiple types. Unions are commonly used in low-level byte manipulation such as reading hardware registers or parsing network packets.

Reading a member other than the last one written is "undefined behavior" according to the C standard. However, reading byte representations through an unsigned char member is explicitly permitted by the standard. Use the tagged union pattern when you need to safely work with multiple types.

For a related data structure where all members are independent, use struct. To enumerate a set of related constants, see enum.

If you find any errors or copyright issues, please .