Reputation: 7473
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
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 amem-initializer
, the initialization specified by themem-initializer
is performed, and the non-static data member’sbrace-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 emptycompound-statement
.
This would mean the implicitly generated (default) constructor has no mem-initializer
s 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
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