Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Array member initialization, gcc vs. clang

51 views
Skip to first unread message

Juha Nieminen

unread,
Jul 5, 2016, 7:01:04 AM7/5/16
to
Consider the following code:

//--------------------------------------------------
struct A { int values[5]; A(): values{} {} };
struct B { int values[5] = {}; };
int main()
{
const A a; // Works
const B b; // Compiler error
}
//--------------------------------------------------

This compiles with all recent versions of gcc. However, all recent versions
of clang complain about the "const B b;" line, saying:
"error: default initialization of an object of const type 'const B' without
a user-provided default constructor"

Which one is right?

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Alf P. Steinbach

unread,
Jul 5, 2016, 7:57:02 AM7/5/16
to
On 05.07.2016 13:00, Juha Nieminen wrote:
> Consider the following code:
>
> //--------------------------------------------------
> struct A { int values[5]; A(): values{} {} };
> struct B { int values[5] = {}; };
> int main()
> {
> const A a; // Works
> const B b; // Compiler error
> }
> //--------------------------------------------------
>
> This compiles with all recent versions of gcc. However, all recent versions
> of clang complain about the "const B b;" line, saying:
> "error: default initialization of an object of const type 'const B' without
> a user-provided default constructor"
>
> Which one is right?

Offhand, strong gut feeling, clang's error is correct.

Because the rationale for the old rule is that a default initialized
instance is not very useful as a constant, so that a constant needs to
be explictly specified, hence, user provided default constructor or (not
mentioned in the error message) explicit initializer.

Anyway it's IMHO best to proceed as if clang is correct here. ;-)


Cheers & hth.,

- Alf

Alain Ketterlin

unread,
Jul 5, 2016, 12:23:10 PM7/5/16
to
Juha Nieminen <nos...@thanks.invalid> writes:

> Consider the following code:
>
> //--------------------------------------------------
> struct A { int values[5]; A(): values{} {} };
> struct B { int values[5] = {}; };
> int main()
> {
> const A a; // Works
> const B b; // Compiler error
> }
> //--------------------------------------------------
>
> This compiles with all recent versions of gcc. However, all recent versions
> of clang complain about the "const B b;" line, saying:
> "error: default initialization of an object of const type 'const B' without
> a user-provided default constructor"
>
> Which one is right?

In N4296: §8.5p7 is:

| To default-initialize an object of type T means:
|
| (7.1) — If T is a (possibly cv-qualified) class type (Clause 9),
| constructors are considered. The applicable constructors are enumerated
| (13.3.1.3), and the best one for the initializer () is chosen through
| overload resolution (13.3). The constructor thus selected is called,
| with an empty argument list, to initialize the object.
|
| (7.2) — If T is an array type, each element is default-initialized.
|
| (7.3) — Otherwise, no initialization is performed.
|
| 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 I think clang is right.

-- Alain.

woodb...@gmail.com

unread,
Jul 5, 2016, 12:36:21 PM7/5/16
to
It sounds like clang is right according to the
letter of the law. I'd prefer a warning though
in that case rather than an error.

Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net

Chris Vine

unread,
Jul 5, 2016, 1:29:43 PM7/5/16
to
Zero initialization of the member array with either of these will work
with clang:

const B b{};
const B b = {};

I suppose the error is sort-of useful where the struct has member data,
but somewhat annoying when you are only interested in compile time
template values. So given a list of compile-time integers as follows

struct int_list<int...> {};

the following will also fail with clang unless you zero initialize the
(non-existent) member data of the struct, or remove the explicit
constexpr specifier:

constexpr int_list<1, 3, 5, 7, 9> odds; // won't compile

As you say I suspect (but don't know) that this behaviour is what the
standard requires.

Chris

Juha Nieminen

unread,
Jul 6, 2016, 2:13:16 AM7/6/16
to
Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
>> struct A { int values[5]; A(): values{} {} };
>> struct B { int values[5] = {}; };

> hence, user provided default constructor or (not
> mentioned in the error message) explicit initializer.

What do you mean "explicit initializer"? The array is being initialized
in both cases.

Alf P. Steinbach

unread,
Jul 6, 2016, 3:36:00 AM7/6/16
to
On 06.07.2016 08:13, Juha Nieminen wrote:
> Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
>>> struct A { int values[5]; A(): values{} {} };
>>> struct B { int values[5] = {}; };
>
>> hence, user provided default constructor or (not
>> mentioned in the error message) explicit initializer.
>
> What do you mean "explicit initializer"? The array is being initialized
> in both cases.

Explicit initializer in the declaration of each constant.

E.g.,

int const x = 42; // ← An explicit initializer.
0 new messages