If we start from the draft C++14 standard section 7.1.5
[dcl.constexpr] we can find the requirements for a constexpr object declaration are:
A constexpr specifier used in an object declaration declares the object as const. Such an object shall have
literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.19).
So is f
is a literal type?
Section 3.9
[basic.types] says:
A type is a literal type if it is:
and covers classes in the following bullet:
So we are okay on the first and third bullet. To cover the second bullet, we could note that f
is an aggregate but if we modify the example slightly, for example if f
looked like this:
struct f {
private:
int x = 0 ;
} ;
which would not be an aggregate in either C++11 or C++14 but the issue would still exist. Then we need to show it has a constexpr constructor. Does f
have a constexpr constructor?
As far as I can tell section 12.1
[class.ctor] says yes:
[...] If that user-written default constructor would satisfy the requirements of a constexpr constructor (7.1.5),
the implicitly-defined default constructor is constexpr. [...]
But we are unfortunately required to have a user-provided constructor by section 8.5
which says:
If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type
with a user-provided default constructor.
So it looks like clang is correct here and if we look at the following clang bug report: "error: default initialization of an object of const type 'const Z' requires a user-provided default constructor" even when no constructor needed. So clang is basing their lack of support for this due to defect report 253 which does not currently have a proposed wording and it says (emphasis mine):
Paragraph 9 of 8.5 [dcl.init] says:
If no initializer is specified for an object, and the object is of
(possibly cv-qualified) non-POD class type (or array thereof), the
object shall be default-initialized; if the object is of
const-qualified type, the underlying class type shall have a
user-declared default constructor. Otherwise, if no initializer is
specified for an object, the object and its subobjects, if any, have
an indeterminate initial value; if the object or any of its subobjects
are of const-qualified type, the program is ill-formed.
What if a const POD object has no non-static data members? This wording requires an empty initializer for such cases
[...]
Similar comments apply to a non-POD const object, all of whose non-static data members and base class subobjects have default constructors. Why should the class of such an object be required to have a user-declared default constructor?
The defect report is still open but the last comment on it says:
If the implicit default constructor initializes all subobjects, no initializer should be required.
and also notes:
This issue should be brought up again in light of constexpr constructors and non-static data member initializers.
Note the constraints on const qualified types moved around in section 8.5
since the defect report came about. This was due to proposal N2762: Not so Trivial Issues with Trivial which was pre C++11.
Although the defect report is still open, given the constexpr changes and non-static data member initializers it does not seem like a necessary restriction anymore. Especially considering the following requirement on a constexpr constructor:
- every non-variant non-static data member and base class sub-object shall be initialized (12.6.2);