Home c++ Why do you need a union?

Why do you need a union?




For example,

  float fl,
  unsigned int uinteg,
  char ch,
  int integ
} foo;

All this is stored mixed in one area of ​​memory. What’s the point, because once you set the values ​​

foo.fl = 3.14f;
foo.uinteg = 666;
foo.ch = 'a';
foo.int = -25;

will not be able to get them back – will everything get mixed up? A way to save a couple of bytes or a couple of clock cycles and still keep readability? Not writing 4 different functions, but writing one that accepts a union and in it you already decide what to do? In this case, wouldn’t it be easier to accept void * and then cast to the type you need? As an example of “Just cast” I will give the following code:

Classic example:

typedef enum {STR, INT} tType;
typedef struct {
  tType typ; // typ is separate.
  union {
    int ival; // ival and sval occupy same memory.
    char * sval;
} tVal;
void printer (tVal uni)
  if (uni.type == INTEGER) // blah-blah
    uni.ival // Use integer
    ini.sval // Otherwise

The printer function can be rewritten like this:

void printer (void * data, tType typ)
  if (tType == INTEGER)
    (int *) data // Do something

Another example:

  int a;
  int b;
  int c;
} bar;
bar.a = 20;
bar.b = 50; // Lost a value :(

Again, what’s the point if I can first create a separate variable int a = 20; and then change its value a = 50; and the effect is exactly the same right? Looks like powerful sorcery.

Answer 1, authority 100%

Union -s (unions) are used in two cases:

  1. To create a “generic” data type capable of storing not a single, but one of the predefined types. To do this, an integer field is added to the union indicating the type of data currently stored:

    struct variant
      union tag_value
        int intValue;
        float floatValue
      } value;
      unsigned storedType;

    One example of this in real life is the structure VARIANT from Windows API.

    In other words, it is the predecessor of modern boost :: variant , QVariant , etc. However, the above classes can store non-primitive types (with constructors, destructors and operators copy), but union is not.

  2. To convert between incompatible types. Traditionally, the conversion operator (T) or reinterpret_cast & lt; & gt; is used for this purpose. However, these methods are dangerous by violating strict aliasing rule and, as a result, generating an undefined (that is, unpredictable) behavior.

    Correct conversion methods are either memcpy (a similar call to which is thrown by the compiler), or using union .

    UPD: Attention! Conversion via union is valid only in C , but not in C++. In the answer to the question “Accessing inactive union member and undefined behavior?” references are made to the following clauses of the standards:

    • (no explicit permission for type punning)

      9.5 [class.union]

      Only one non-static field can be active in a union at a time; therefore, there can be no more than one value in the union at any given time.

      9.5 Unions [class.union]

      In a union, at most one of the non-static data members can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.

Answer 2, authority 28%

One practical way to use a union is to access the bits of the information being passed. Let’s say information is transmitted bit by bit at a time 32 bits.

struct _info_s
 uint32_t info_a: 2;
 uint32_t info_b: 10;
 uint32_t info_c: 8;
 uint32_t info_d: 5;
 uint32_t info_e: 5;
 uint32_t info_f: 2;
} __ atributte __ ((packed));
typedef struct _info_s info_s;
union _total_u
 uint32_t array;
 info_s info;

When reading / writing, we can immediately operate on uint32_t , but access to bits appears immediately.

Answer 3, authority 24%

Here’s what Björn Stroustrup answered a similar question to me at one time:

Unions are used when you want to save space by reusing space for
information one type at a time. I don’t use them much.

In other words, in our time they are generally not needed.

Answer 4, authority 10%

If I understand correctly, this is a combination of variables in memory. Sometimes och is convenient if you want to see a variable in a different light or you want to access only part of the variable …

For example, String can be interpreted as byte [] array or byte [] [2] rectangular array, and integer can be decomposed into byte_lo and byte_hi

Answer 5

union is a very useful thing when working with microcontrollers when it is necessary to process data arriving in a “raw” form (for example, when transferring over a CAN network or ethernet).
For example, when transmitting over an information network, two types of messages are possible:

typedef struct {
 char id;
 unsigned int code1;
 unsigned int code2;
} Msg1;
typedef struct {
 char id;
 char code_error;
} Msg2;

Create a union

union {
 char data [maxLen];
 Msg1 msg1;
 Msg2 msg2;

Create a variable

DATA data;

We write the received data into the data.data variable, and interpret the data in messages using the values ​​data.msg1 or data.msg2 .

You can also do without union by directly converting to point to “raw” data into a pointer of one of the types of messages and work with message fields, but when you enable optimization (for example -O2 or -O3), this code stops working. It is necessary to add the volatile keyword everywhere when declaring variables.

Answer 6

As already described, union is very useful when working with microcontrollers, for example, to save memory, you can declare a structure of flags (or values), bind the size in bits and add a variable comparable to the desired bit size.

typedef union {
 struct {
 bool flag1: 1;
 bool flag2: 1;
 bool flag3: 1;
 bool flag4: 1;
bool flag5: 1;
 uint8_t param: 3;
 }; // total 8 bits
 uint8_t flags; // variable of the same size or larger

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions