Constructor
Constructor

Reputation: 7473

Visual C++ initialization inconsistence with gcc and clang

The following piece of code prints 0 compiled with vc++ and prints 1 compiled with g++ or clang++:

#include <iostream>
#include <vector>

struct S
{
    S() = default;

    std::vector<int> v{0};        
};

int main()
{
    std::vector<S> s{{}};

    std::cout << s.front().v.size() << std::endl;
}

Is it a bug in vc++?

If a user-defined constructor is provided (S() {}; instead of S() = default;) vc++ starts to print 1, too.

Upvotes: 3

Views: 101

Answers (2)

rubenvb
rubenvb

Reputation: 76519

In reading the Standard (C++11 n3485), 12.6.2/9 states that:

If a given non-static data member has both a brace-or-equal-initializer and a mem-initializer, the initialization specified by the mem-initializer is performed, and the non-static data member’s brace-or-equal-initializer is ignored.

So the question becomes if the default, i.e. the implicitly defined constructor contains a mem-initializer or not.

Section 12.1/6 states:

The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement.

This would mean the implicitly generated (default) constructor has no mem-initializers and should indeed use the in-class initializer (the brace-or-equal-initializer in the above quote).

MSVC is wrong here (no surprise there, really).

Upvotes: 3

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145249

This is not an answer but a comment requiring code.

The following illustrates the compiler differences more clearly, I think:

#include <iostream>
#include <vector>

struct S
{
    S() = default;

    std::vector<int> v = std::vector<int>(13);
};

int main()
{
    std::vector<S> s{{}};
    std::cout << s.front().v.size() << std::endl;
}

Here g++ MinGW 5.1.0 reports 13 items, while MSVC 2015 update 2 reports 0 items.

I.e. g++ uses the initializer specified in the class, while MSVC uses the one specified in the declaration of s. To me that looks like a problem with g++. But I'm not sure: the only sure thing is that both can't be right.

Upvotes: 1

Related Questions