<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">The latest version of MSVC does not reject:</div><div class="gmail_quote"><div class="gmail_quote">Compiled with /EHsc /nologo /W4 /c</div><div class="gmail_quote">main.cpp</div><div class="gmail_quote">main.cpp(3): warning C4100: 'x': unreferenced formal parameter</div><div class="gmail_quote">main.cpp(14): warning C4100: 'argv': unreferenced formal parameter</div><div class="gmail_quote">main.cpp(14): warning C4100: 'argc': unreferenced formal parameter</div><div class="gmail_quote">main.cpp(16): warning C4101: 'list': unreferenced local variable</div><div class="gmail_quote"><br></div><div class="gmail_quote">Compilation successful!</div><div class="gmail_quote"><br></div><div class="gmail_quote">Total compilation time: 109ms</div><div class="gmail_quote"><br></div><div class="gmail_quote">You are quoting the C++98 text, C++11 has a feature called "unrestricted unions": <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf</a></div><div class="gmail_quote"><br></div><div class="gmail_quote">It looks like there is a bug here though.  We allow unrestricted unions in C++98 mode if the original union declaration is dependent.</div></div><div class="gmail_quote"><br></div><div class="gmail_quote">On Mon, Dec 15, 2014 at 1:04 AM, Florian Merz <span dir="ltr"><<a href="mailto:florian.merz@kit.edu" target="_blank">florian.merz@kit.edu</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi everyone,<br>
<br>
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).<br>
<br>
I tried to extract a minimal example for this:<br>
<br>
class X {<br>
public:<br>
    X(int x) {}<br>
};<br>
<br>
template<class Payload><br>
class List {<br>
    union PayloadOrNext {<br>
        Payload payload;<br>
        PayloadOrNext *next;<br>
    };<br>
};<br>
<br>
int main(int argc, char **argv)<br>
{<br>
    List<X> list;<br>
}<br>
<br>
The standard says (in 9.5.1):<br>
<br>
"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."<br>
<br>
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.<br>
<br>
So my question is: Why does template-with-a-union-member make a difference and what does the generated code actually look like?<br>
<br>
Best regards,<br>
 Florian Merz<br>
______________________________<u></u>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div></div>