Union containing volatile structures

This is similar to POD structures containing a constant element , but it seems to be the other way around.

#include <iostream> struct A { int a; }; union U { volatile A a; long b; }; int main() { U u1; U u2; u1.aa = 12; u2 = u1; std::cout << u2.aa << std::endl; return 0; } 

g ++ 4.8.3 compiles this code without errors and works correctly:

 $ g++ -std=c++03 a.cpp -o a_gcc $ ./a_gcc 12 

But clang ++ 3.5.1 creates an error (I manually wrapped the error message so that the code window would not scroll):

 $ clang++ -std=c++03 a.cpp -o a_clang a.cpp:8:7: error: member function 'operator=' not viable: 'this' argument has type 'volatile A', but function is not marked volatile union U ^ a.cpp:3:8: note: 'operator=' declared here struct A ^ a.cpp:20:5: note: implicit copy assignment operator for 'U' first required here u2 = u1; ^ 1 error generated. 

Does C ++ 03 allow a program to copy-assign a union containing mutable structures? I could not find anything in the C ++ 03 standard that defines the default copy constructor of a union.

I would like to know which compiler is correct, or if the standard is not clear at this point.

Edit: I found out that if I use the copy construct instead of the copy destination, then both clang ++ and g ++ will compile the program without errors. In particular, if I change main as follows:

 int main() { U u1; u1.aa = 12; U u2 = u1; std::cout << u2.aa << std::endl; return 0; } 

.. then it will work. I wonder why they are referred to in other words, clang ++.

+6
source share
1 answer

In C ++ 11, the copy constructor of a union can be removed. We see this from a note in [class.union], Β§ 9.5 in N4140:

[Note: if any non-static data member from the union has a non-trivial default constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move assignment operator (12.8) or destructor (12.4) ), the corresponding membership function of the union must be provided by the user or it will be implicitly removed (8.4.3) to combine. -end note]

And in [class.copy], Β§12.8 / 25, we see that our union has a nontrivial copy constructor:

The copy / move assignment operator for class X is trivial if it is not provided by the user, its list of parameter parameters is equivalent to the list of parameter types of the implicit declaration, and if ... - [..]
- class X has non-static data elements of type volatile-qualified and

But this particular line in [class.copy] was only added as a result. Is the volatile-qualified type really a POD? Prior to this, such a class would still be considered a trivial copy constructor.

So, I understand that in C ++ 03 there is no indication that the union constructor should be removed, but in C ++ 11 there are some indications of this, but it is not normative.

0
source

Source: https://habr.com/ru/post/982008/


All Articles