Reputation: 3179
Is this code valid with C++14
using namespace std;
struct Point
{
int x = 0;
int y = 0;
};
Point p2 {1, 1};
It compiles fine with clang++ 7.0, it doesn't work with G++ 4.9 in both cases I pass --std=c++1y to the compiler.
In G++ it works when I remove the default values from the struct definition.
g++ test_constexpr_ctor.cc --std=c++1y -o test
test_constexpr_ctor.cc:7:15: error: no matching function for call to ‘Point::Point(<brace-enclosed initializer list>)’
Point p2 {1, 1};
^
test_constexpr_ctor.cc:7:15: note: candidates are:
test_constexpr_ctor.cc:1:8: note: constexpr Point::Point()
struct Point
^
test_constexpr_ctor.cc:1:8: note: candidate expects 0 arguments, 2 provided
test_constexpr_ctor.cc:1:8: note: constexpr Point::Point(const Point&)
test_constexpr_ctor.cc:1:8: note: candidate expects 1 argument, 2 provided
test_constexpr_ctor.cc:1:8: note: constexpr Point::Point(Point&&)
test_constexpr_ctor.cc:1:8: note: candidate expects 1 argument, 2 provided
Upvotes: 7
Views: 736
Reputation: 16685
The code you posted is absolutely correct.
However the behaviour you have is a not yet closed bug of G++ version 4.9.1. Actually, it may be a duplicate and closed in some other bug report, because the problem is fixed since g++
5.1.0 or maybe even earlier version. To find actual bug you may use bugzilla's search.
Upvotes: 3
Reputation: 29966
The code is valid.
List-initialization of an object or reference of type T is defined as follows: — If T is an aggregate, aggregate initialization is performed
An aggregate is an array or a class (Clause 9 ) with no user-provided constructors ( 12.1 ), no private or protected non-static data members (Clause 11 ), no base classes (Clause 10 ), and no virtual functions ( 10.3 ).
Note that in c++11 this definition looked different (emphasis mine):
An aggregate is an array or a class (Clause 9 ) with no user-provided constructors ( 12.1 ), no brace-or-equal- initializer s for non-static data members ( 9.2 ), no private or protected non-static data members (Clause 11 ), no base classes (Clause 10 ), and no virtual functions ( 10.3 ).
Since this part is removed in c++14, your struct is definitely an aggregate and thus aggregate initialization should be performed.
This is fixed in gcc5 (search the changes list for "aggregates with non-static data member initializers"). I wouldn't call it a "bug" though, it's rather the gcc team only implemented that change in gcc 5.1.0.
Upvotes: 3