Unions
- A union in ‘C’ is similar to a structure except that all of its members start at the same location in memory.
- A union variable can represent the value of only one of its members at a time.
Difference between union and structure
Structure memory allocation
struct address { uint16_t shortAddr; uint32_t longAddr; };
Here you have a structure called address, and you have 2 member elements. uint16 short address and uint32 long address.
How does this structure variable get saved in the memory?
This is how it is stored, as shown in Figure 2. The first short address will be stored, so it needs 2 bytes. After that, there will be padding. And after that long address will be stored here. So, it totally takes 8 bytes.
Union memory allocation
Look at the union. Here replace the keyword struct by the keyword union. That’s all you have to do.
Now, look at the memory allocation for the union. Here, just 4 bytes are being used. So, the first thing you have to note in a union is, the memory consumed by the union is equal to the size of its biggest member element.
Here, the long address is the biggest member element and its size is 4. So, that is the reason this union consumes 4 bytes in memory.
What is the use of a union?
Use unions instead of structure to save memory when access to its member elements is mutually exclusive.
For example, let’s say you are sending one packet from the transmitter to the receiver, you either send the packet using a long address or a short address. So, there is mutual exclusion. You don’t send the packet using both a long address and a short address. You use either one. In that case, instead of creating a struct, you can create a union.
So, here during the operation either the uint16_t shortAddr field will be utilized or this field uint32_t longAddr will be utilized. That’s why the struct address consumes 8 bytes and this union address consumes 4 bytes. That is the difference between a union and a structure.
Now let’s understand the behavior of union by writing one simple program.
Here is a program, as shown in Figure 4. I have a union definition called union Address. And after that I created a union variable, that is addr. And after that, I dereference the addr variable to set the value for shortAddr = 0xABCD; and after that addr.longAddr = 0XEEEECCCC. Then, print the values of these member elements using printf statements.
When you execute this program you find this result. Short address = 0xCCCC and long address = 0xEEEECCCC.
How do you analyze this?
First store the value 0xABCD into a short variable. So, a CD is stored in the 0XE00 address and AB is stored in 0XE01.
After that, you are going to store the value 0xEEEECCCC into longAddr. So, that value will be overwritten now.
Here what happens is, the CD will be overwritten with CC, and AB will be overwritten with CC, so because the format is little-endian, that’s why I am writing in reverse. And 0xE02 address will be EE and the 0xE03 address will be EE. That’s why, after the second initialization the memory looks like this CCCC EEEE.
After that in printf, you are reading CC CC this member element. That’s why it is returning the first two bytes, that is CCCC. And after that, you are again reading this longAddr, so it is returning this whole thing. So, that’s why the output looks like this.
The key takeaway from this article is very simple, addr.shortAddr = 0XABCD this initialization is overwritten in the memory by addr.LongAddr = 0XEEEECCCC this initialization.
That’s why you should be careful while using the union variables.
Use the union variable when the access to the member elements is mutually exclusive.
In the following article, let’s understand the applicability of unions in embedded system code.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1