[C] Union Types

Union Types tend to have bad reputation: making code hard to understand, making code error-prone …

I do not recommend to use union types. Just understand what it is (the concept is not hard) in order to understand the existing code.

 

1. What is an Union Type

When you define a struct type, each member has its own memory space. They are independent each other.

Union types are different. All members of a union type share the same starting memory address. Confused?

Suppose you want to define a type for an ip address which can represent both IPv4 (4 bytes) and IPv6 (16 bytes). You can use a struct type to save 2 addresses separately (total 20 bytes).  But if you use a union type, it requires 16 bytes and the first 4 bytes are shared by both.

 

2. Declaring Union Types

You can declare the union type just like the struct type. By using the “typedef” keyword, you can create a new type.

typedef struct
{
  unsigned char v4[4];
  unsigned char v6[16];
} IPAddrStruct;

typedef union
{
  unsigned char v4[4];
  unsigned char v6[16];
} IPAddr;

void TypeTest1()
{
  printf("%i n", sizeof(IPAddrStruct)); // 20
  printf("%i n", sizeof(IPAddr)); // 16
}

Note that you can use the “.” notation to access a member of a struct type.

 

3. Using Union Types

You can use the “.” notation or the “->” notation to refer to the member of a union.

But you need to rememeber that members are overlapped each other and are not meant to be used together. Please look at the following example.

IPAddr ipv4 = { 100, 10, 10, 202 };
printf("%i.%i.%i.%i n", ipv4.v4[0], ipv4.v4[1], ipv4.v4[2], ipv4.v4[3]);

IPAddr ipv6;
unsigned char addr[] = { 10, 10, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 100, 1, 0, 1 };
for(int i=0; i<16; i++)
  ipv6.v6[i] = addr[i];

for(int i=0; i<15; i++)
  printf("%i.", ipv6.v6[i]);
printf("%i n", ipv6.v6[15]);

printf("%i.%i.%i.%i n", ipv6.v4[0], ipv6.v4[1], ipv6.v4[2], ipv6.v4[3]); // possible but do not use like this

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s