Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you assign the value of one union member to another?

Consider the following code snippet:

union
{
   int a;
   float b;
};

a = /* ... */;

b = a;               // is this UB?
b = b + something;

Is the assignment of one union member to another valid?

like image 862
The Mask Avatar asked Feb 25 '14 18:02

The Mask


People also ask

What is the value of any variable in an union?

In contrast with a record (or structure), which could be defined to contain a float and an integer; in a union, there is only one value at any given time. A union can be pictured as a chunk of memory that is used to store variables of different data types.

How we can access the members of union?

Access members of a union We use the . operator to access members of a union. And to access pointer variables, we use the -> operator.

How many union members can be accessed at a time?

Only one union member should be accessed at a time, as different variable share same space in memory. Example union shared { char c; int i; };

What are the limitations of union in C?

Disadvantages of Structure and Union in C In a union you can use only one union member at a time. All the union variables cannot be initialized or used with varying values at a time. Union assigns one common storage space for all its members. Structure is slower because it requires storage space for all the data.


1 Answers

Unfortunately I believe the answer to this question is that this operation on unions is under specified in C++, although self assignment is perfectly ok.

Self assignment is well defined behavior, if we look at the draft C++ standard section 1.9 Program execution paragraph 15 has the following examples:

void f(int, int);
void g(int i, int* v) {
    i = v[i++]; // the behavior is undefined
    i = 7, i++, i++; // i becomes 9

    i = i++ + 1; // the behavior is undefined
    i = i + 1; // the value of i is incremented

    f(i = -1, i = -1); // the behavior is undefined
}

and self assignment is covered in the i = i + 1 example.

The problem here is that unlike C89 forward which supports type-punning in C++ it is not clear. We only know that:

In a union, at most one of the non-static data members can be active at any time

but as this discussion in the WG21 UB study group mailing list shows this concept is not well understood, we have the following comments:

While the standard uses the term "active field", it does not define it

and points out this non-normative note:

Note: In general, one must use explicit destructor calls and placement new operators to change the active member of a union. — end note

so we have to wonder whether:

b = a;

makes b the active member or not? I don't know and I don't see a way to prove it with the any of the current versions of the draft standard.

Although in all practicality most modern compilers for example gcc supports type-punning in C++, which means that the whole concept of the active member is bypassed.

like image 197
Shafik Yaghmour Avatar answered Sep 21 '22 15:09

Shafik Yaghmour