7

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
5

2 Answers 2

3

The code is valid.

  1. (8.5.4/3):

List-initialization of an object or reference of type T is defined as follows: — If T is an aggregate, aggregate initialization is performed

  1. An aggregate in c++14 is defined as (8.5.1/1):

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.