Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why wrap a struct with a union?

Tags:

c

struct

I saw a code snippet from a good answer for Is it possible to insert three numbers into 2 bytes variable?

For example, I want to store date which contain days, months, years.

  • days -> 31, months -> 12, years -> 99.

I want to store 31, 12, 99 in one variable, and will use shift operators << and >> to manipulate it.

//Quoted: the C code from that answer
    union mydate_struct {
        struct {
            uint16_t day : 5;    // 0 - 31
            uint16_t month : 4;  // 0 - 12
            uint16_t year : 7;   // 0 - 127
        };
        uint16_t date_field;
    };

Now, my question is to why wrap the struct with a union? What are the special benefits besides memory related concern?
PS: I know some typical usage to make sure memory size with union.

Because if it is just to use struct, it seems more direct and simple to use:

   typedef struct {
        uint16_t day : 5;    // 0 - 31
        uint16_t month : 4;  // 0 - 12
        uint16_t year : 7;   // 0 - 127
   } mydate_struct;

Update1:

Some conclusion about benefits to wrap a union here:

  • Can initailize the year, month and day simultaneously

The advantage of using the union is that give union my_datestruct u; you can write u.date_field = 0x3456; and initialize the year, month and day fields simultaneously. It is defined by the implementation what that does, and different implementations could define it differently. There's a modest chance that the year will be 0x56, the month 0x08, and the day 0x06 (aka 86-08-06 — century not clearly defined); there's also a modest chance that the year will be 0x1A, the month 0x02, and the day 0x1A (aka 26-02-26 — century still not clearly defined). People have forgotten Y2K already. ----comment of @Jonathan Leffler

  • You can read/write the whole number at once.(----comment of @StenSoft)
like image 213
Eric Tsui Avatar asked Jun 09 '26 22:06

Eric Tsui


2 Answers

An union means that every part in it will use the same memory, so you can use the first or the second part (which can be completely different things). In your case, it´s either the whole struct or the uint16_t date_field.

In context of the linked question, the writer intended to use it to convert a struct with two byte size to a two byte integer and vice-versa. Assign something to the struct and read the int value from the same memory. But this is not allowed in C++ and may not work (multitude of reasons...). It´s not possible to arbitrarily switch between what part is used.

like image 191
deviantfan Avatar answered Jun 12 '26 13:06

deviantfan


Union will share the memory among the members variables. So size of a union will be the size of the biggest element of its member variables. That is the reason struct wrapped within the union with variable uint16_t date_field;

So user can use 16 bits of memory for struct or variable date_field to keep the data.

like image 24
Steephen Avatar answered Jun 12 '26 11:06

Steephen