2

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.

Versions affected

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.

Question

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?

What I found so far

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.

5
  • Please suggest better tags. Commented Feb 15, 2017 at 13:46
  • looks like this explains it. Commented Feb 15, 2017 at 13:49
  • So newer versions of GCC and Clang are broken with regards to the standard? Surely, there must be a rule in the standard that allows the current behavior of these compilers. Your linked answer, while useful, did not answer this question to me. Commented Feb 15, 2017 at 13:59
  • 1
    This might be the answer. It links to this issue of the Standard Committee for C++11. Now, only a link to which resolution the Standard came is needed. Commented Feb 15, 2017 at 14:03
  • You are correct, it's Core issue 253. GCC documented its change of behaviour for gcc 4.6 at gcc.gnu.org/gcc-4.6/changes.html#cplusplus Commented Feb 15, 2017 at 14:32

1 Answer 1

4

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.

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

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.