Quantcast
Channel: Visual C forum
Viewing all articles
Browse latest Browse all 15302

This question is about N3797 §12.1/4 or N3337 12.1/5

$
0
0

The quoted paragraphs in the two versions of the Draft (N3797 and N3337) are the same:

A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.4). An implicitly-declared default constructor is an inline public member of its class. A defaulted default constructor for class X is defined as deleted if:

  • X is a union-like class that has a variant member with a non-trivial default constructor,
  • any non-static data member with no brace-or-equal-initializer is of reference type,
  • any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-
    initializer does not have a user-provided default constructor,
  • X is a union and all of its variant members are of const-qualified type (or array thereof),
  • X is a non-union class and all members of any anonymous union member are of const-qualified type (or array thereof),
  • any direct or virtual base class, or non-static data member with no brace-or-equal-initializer, has class type M (or array thereof) and either M has no default constructor or overload resolution (13.3) as applied to M’s default constructor results in an ambiguity or in a function that is deleted or inaccessible from the defaulted default constructor, or
  • any direct or virtual base class or non-static data member has a type with a destructor that is deleted or inaccessible from the defaulted default constructor.

I'll start with the 4th bullet point. As you can see here (http://rextester.com/HCPP94321) and here (http://rextester.com/HHQUB4028), the results vary for the compilers VS2013, clang and g++, and it appears to me that the only one respecting this bullet point in the Standard is clang, as I'll try to explain below:

The first snippet

#include <iostream>

union U
{
    const int i;
    const double x;
    char c;
};

int main()
{
    U u;
}

shows one non-constant variant-member in the union U. This should compile without a problem. But that's not what happens. I summarize below the results for the three compilers:

VS2013    -  error C2512: 'U' no appropriate default constructor available

clang        -  Ok (no error message)

g++          -  error: uninitialized const member in 'Union U'
                    note: 'U::i' should be initialized
                    error: uninitialized const member in 'Union U'
                    note: 'U::x' should be initialized

The second snippet

#include <iostream>

union U
{
    const int i;
    const double x;
    const char c;
};

int main()
{
    U u;
}

shows all variant members in the Union constant, which is the subject of the 4th bullet point above. See below the results for each compiler:

VS2013   -  the same error C2512

clang       -  error: call to implicitly-deleted default constructor of 'U'
                   note: default constructor of 'U' is implicitly deleted because all data members are const-qualified

g++        -   the same errors listed above

Assuming clang is correct, I can understand the reason for the implicit deletion of the default constructor in this case, i.e., to avoid an uninitialized object of a union, where all variant-members are constant.

Now lets consider the third bullet point above:

  • any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-
    initializer does not have a user-provided default constructor,

Here I don't see the need for this implicit deletion of the default constructor, for the compiler will always show an error for a class constant member which is not initialized, as you can see here (http://rextester.com/AOI2981). That is, what's the reason for this bullet point?


Viewing all articles
Browse latest Browse all 15302

Trending Articles