Reputation: 16197
The following code compiles with some versions with GCC and some versions of Clang (see below which versions).
struct my_struct {};
int main(int argc, char** argv) {
const my_struct my_object;
return 0;
};
Compile with :g++ clang_error.cpp
and clang++ clang_error.cpp
. Where I had g++ at 4.8.4 and clang++ at 3.6.0.
The error message is:
clang_error.cpp:7:19: error: default initialization of an object of const type 'const my_struct' without a user-provided default constructor
const my_struct my_object;
^
clang_error.cpp:7:28: note: add an explicit initializer to initialize 'my_object'
const my_struct my_object;
^
= {}
1 error generated.
Using the Compiler Explorer here, I can see that GCC up to 4.5.4 is affected. Clang is affected up to 3.9.0.
My question is: What does the C++ standard say about this? Ideally, I'd care about C++14 but I'm not picky there.
Is the above example code standard-conformant?
I found the following in Draft N3797 of C++14.
§ 7.1.6.1 The cv-qualifiers [dcl.type.cv]
2 [ Note: Declaring a variable const can affect its linkage (7.1.1) and its usability in constant expressions (5.19). As described in 8.5, the definition of an object or subobject of const-qualified type must specify an initializer or be subject to default-initialization. — end note ]§ 8.5
7 To default-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) for T is called (and the initialization is ill-formed if T has no default constructor or overload resolution (13.3) results in an ambiguity or in a function that is deleted or inaccessible from the context of the initialization);
— if T is an array type, each element is default-initialized;
— otherwise, no initialization is performed.
Upvotes: 2
Views: 932
Reputation: 238311
What does the C++ standard say about this?
Is the above example code standard-conformant?
In C++14, it is non-conformant:
n4431 (2015) standard draft [dcl.init] / 7:
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.
my_struct
has no user-provided default constructor, so you shall not default-initialize.
However, some newer compilers appear to have chosen to relax the rule, possibly because it is subject to a defect report: DR 253.
The upcoming standard has changed wording:
Current (2017) standard draft [dcl.init] / 7:
A class type T is const-default-constructible if default-initialization of T would invoke a user-provided constructor of T (not inherited from a base class) or if
(7.4) each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible,
(7.5) if T is a union with at least one non-static data member, exactly one variant member has a default member initializer,
(7.6) if T is not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and
(7.7) each potentially constructed base class of T is const-default-constructible.
If a program calls for the default-initialization of an object of a const-qualified type T, T shall be a const-default-constructible class type or array thereof.
The wording is a bit ambiguous to me, but I think that since my_struct
has no members that violate 7.4 (and is not a union, so 7.5 does not apply, has no union members so 7.6 does not apply and no bases, so 7.7 does not apply), it is const-default-constructible and therefore the example will be conformant.
Upvotes: 4