[cfe-dev] Puzzling clang behavior with classes in unions

Florian Merz florian.merz at kit.edu
Mon Dec 15 01:04:06 PST 2014


Hi everyone,

I stumbled upon a piece of code that Visual Studio rejects (and I 
believe for a good reason), but which clang and gcc both seem to accept 
(but should not, AFAIK).

I tried to extract a minimal example for this:

class X {
public:
     X(int x) {}
};

template<class Payload>
class List {
     union PayloadOrNext {
         Payload payload;
         PayloadOrNext *next;
     };
};

int main(int argc, char **argv)
{
     List<X> list;
}

The standard says (in 9.5.1):

"A union can have member functions (including constructors and 
destructors), but not virtual functions. A union shall not have base 
classes. A union shall not be used as a base class. An object of a class 
with a non-trivial constructor, a non-trivial copy-constructor, a 
non-trivial destructor, or a non-trivial copy assignment operator cannot 
be a member of a union, nor can an array of such objects. If a union 
contains a static data member, or a member of a reference type, the 
program is ill-formed."

X is a class with a non-trivial constructor and is used as a member of 
the union PayloadOrNext (in the template class List), so I'd expect this 
code to be rejected. If I use the union directly (still as a template 
though) or if I replace the template class by a non-template version, 
the code is indeed rejected.

So my question is: Why does template-with-a-union-member make a 
difference and what does the generated code actually look like?

Best regards,
  Florian Merz



More information about the cfe-dev mailing list