6
votes

The code below shows a union-like class with a non-trivial default constructor (member y is initialized with a brace-or-equal-initializer), so if a default constructor for such a class is defaulted, it should be deleted according to §12.1/5 first bullet point. That is, the declaration T t; should not compile, as there is no default constructor for the union T. But the code compiles and executes in clang and GCC.

#include <iostream>
union T
{
    int y{1};
    float x;
    char c;
    T() = default;
};

int main()
{
    T t;
    std::cout << t.y << '\n';
}

EDIT

My question above was wrong right from the start, as the union T is not a union-like class. I just came to know about §9.5/8 in C++11 which says:

A union-like class is a union or a class that has an anonymous union as a direct member. A union-like class X has a set of variant members. If X is a union its variant members are the non-static data members; otherwise, its variant members are the non-static data members of all anonymous unions that are members of X.

Now, consider the snippet below. It doesn't compile because the default constructor for the union is deleted. But I still, don't know which bullet point in §12.1/5 is reponsible for this result. Note that again, the union is not a union-like class and so, the first bullet point in §12.1/5 doesn't apply. But that's what the error message says in both clang and GCC. See live example.

#include <iostream>

union T{
    int y;
    struct A{ int i; A():i{1} {} } a;
};

int main()
{
    T t;
    std::cout << t.a.i << '\n';
}
1
"A default constructor that is defaulted and not defined as deleted is implicitly defined when it is od-rused" Because your constructor appears to be odr-used, shouldn't it be valid code?AndyG
It also compiles for VS 2015 Preview without issues.PaulMcKenzie
What is the purpose of a union that you can't instantiate in any way?Cássio Renan

1 Answers

11
votes

The bullet is

X is a union-like class that has a variant member with a non-trivial default constructor

which is parsed as

X is a union-like class that has (a variant member with a non-trivial default constructor)

i.e., "with a non-trivial default constructor" applies to the type of the variant member, not X.