Bug 55805 - Empty brace-init-list causes warning "missing initializer for member" in C++11
Summary: Empty brace-init-list causes warning "missing initializer for member" in C++11
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-12-25 12:25 UTC by Moritz Bunkus
Modified: 2015-06-16 23:21 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Moritz Bunkus 2012-12-25 12:25:56 UTC
The C++11 standard has this to say on empty brace-init-lists in 8.5.4.3:

  " If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized."

However, g++ issues a warning with "-Wmissing-field-initializers" (which is included in "-Wextra"). Example:

class A {
public:
  int f;
};

int
main() {
  A a3{};
  return 0;
}

Compile with "g++ -Wextra -std=c++11 -o test1 test1.cpp"

clang++ 3.1 does not emit that warning. g++ 4.6, 4.7 and 4.7.2 do (those are the ones I have available here).
Comment 1 Jason Merrill 2013-02-13 05:06:52 UTC
This is the purpose of the warning; to indicate when some fields do not have an explicit initializer during aggregate initialization and are therefore value-initialized.  If you don't want this warning, you can turn it off with -Wno-missing-field-initializers.
Comment 2 Gubbins 2015-06-16 04:08:32 UTC
The original bug report points that in C++11 this is *not* aggregate initialization, but is in fact value initialization (because this is a class type with a default constructor).

Therefore no field initializers are involved. The warning in this situation is surely incorrect? I think the original bug report was correct and the problem should be fixed.
Comment 3 Jonathan Wakely 2015-06-16 10:01:06 UTC
(In reply to Gubbins from comment #2)
> The original bug report points that in C++11 this is *not* aggregate
> initialization, but is in fact value initialization (because this is a class
> type with a default constructor).

No it isn't, it's an aggregate.
Comment 4 Jonathan Wakely 2015-06-16 10:03:37 UTC
(In reply to Gubbins from comment #2)
> Therefore no field initializers are involved. The warning in this situation
> is surely incorrect? I think the original bug report was correct and the
> problem should be fixed.

In any case, there is no warning for any currently supported release, and we are not making any more releases from the gcc 4.7 branch, so there's nothing to fix.
Comment 5 Gubbins 2015-06-16 11:06:46 UTC
(In reply to Jonathan Wakely from comment #4)
> (In reply to Gubbins from comment #2)
> > Therefore no field initializers are involved. The warning in this situation
> > is surely incorrect? I think the original bug report was correct and the
> > problem should be fixed.
> 
> In any case, there is no warning for any currently supported release, and we
> are not making any more releases from the gcc 4.7 branch, so there's nothing
> to fix.

The warning is still produced with gcc 4.9.2 (surely that's supported?)
Comment 6 Gubbins 2015-06-16 11:19:56 UTC
(In reply to Jonathan Wakely from comment #3)
> (In reply to Gubbins from comment #2)
> > The original bug report points that in C++11 this is *not* aggregate
> > initialization, but is in fact value initialization (because this is a class
> > type with a default constructor).
> 
> No it isn't, it's an aggregate.

It's clear that A is an aggregate type, but it is also a class type with a default constructor. Doesn't the quoted section of the C++11 specification therefore state that the object should be value-initialized?
Comment 7 Gubbins 2015-06-16 11:40:11 UTC
(In reply to Gubbins from comment #6)
> (In reply to Jonathan Wakely from comment #3)
> > (In reply to Gubbins from comment #2)
> > > The original bug report points that in C++11 this is *not* aggregate
> > > initialization, but is in fact value initialization (because this is a class
> > > type with a default constructor).
> > 
> > No it isn't, it's an aggregate.
> 
> It's clear that A is an aggregate type, but it is also a class type with a
> default constructor. Doesn't the quoted section of the C++11 specification
> therefore state that the object should be value-initialized?

Anyway, even if this is classified as aggregate initialization (which I believe it is in C++14?), I believe the behaviour should be changed. The distinction between value-initializing a class and aggregate-initializing it with zero field initializers is not a useful one here, IMHO - it's more of a technicality. The result is the same either way (if we, say, add a base class to A in the example then A is no longer aggregate and we get the same initialization outcome with no warning). The current warning behaviour is an annoyance that means I either need to disable -Wmissing-field-initializers (I prefer to keep it enabled) or initialize my object in a more long-winded way.

Coming at it the other way, the point of the warning is presumably to catch errors in which the user accidentally supplies only N initializers for M fields, which is good. I'd suggest that when N=0, it's very unlikely to be an accident!

I propose that the missing-field-initializers warning should not apply to empty aggregate initialization lists, but a separate (new) warning -Wempty-field-initializers could be added which warns for such empty lists if your class happens to be aggregate.
Comment 8 Jonathan Wakely 2015-06-16 11:43:11 UTC
(In reply to Gubbins from comment #5)
> The warning is still produced with gcc 4.9.2 (surely that's supported?)

The warning isn't given for 5.1 and trunk (not sure what I tested before).

(In reply to Gubbins from comment #6)
> It's clear that A is an aggregate type, but it is also a class type with a
> default constructor. Doesn't the quoted section of the C++11 specification
> therefore state that the object should be value-initialized?

Nope.

8.5.4 says:

— Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1).
— Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized. The C++11 wording was fixed by a defect report, see http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1301


(In reply to Gubbins from comment #7)
> Anyway, even if this is classified as aggregate initialization (which I
> believe it is in C++14?), I believe the behaviour should be changed. 

It already has been for gcc-5.
Comment 9 Gubbins 2015-06-16 11:49:42 UTC
(In reply to Jonathan Wakely from comment #8)
> (In reply to Gubbins from comment #5)
> > The warning is still produced with gcc 4.9.2 (surely that's supported?)
> 
> The warning isn't given for 5.1 and trunk (not sure what I tested before).
> 
> (In reply to Gubbins from comment #6)
> > It's clear that A is an aggregate type, but it is also a class type with a
> > default constructor. Doesn't the quoted section of the C++11 specification
> > therefore state that the object should be value-initialized?
> 
> Nope.
> 
> 8.5.4 says:
> 
> — Otherwise, if T is an aggregate, aggregate initialization is performed
> (8.5.1).
> — Otherwise, if the initializer list has no elements and T is a class type
> with a default constructor, the object is value-initialized. The C++11
> wording was fixed by a defect report, see
> http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1301

Oh I see... sorry, I was working off the text from before the defect report.

> (In reply to Gubbins from comment #7)
> > Anyway, even if this is classified as aggregate initialization (which I
> > believe it is in C++14?), I believe the behaviour should be changed. 
> 
> It already has been for gcc-5.

I see, thanks. Will there be no more releases on the 4.9 branch?
Comment 10 Jonathan Wakely 2015-06-16 13:14:39 UTC
(In reply to Gubbins from comment #9)
> I see, thanks. Will there be no more releases on the 4.9 branch?

There will be more. https://gcc.gnu.org/ml/gcc/2015-06/msg00163.html
Comment 11 Gubbins 2015-06-16 23:21:27 UTC
(In reply to Jonathan Wakely from comment #10)
> (In reply to Gubbins from comment #9)
> > I see, thanks. Will there be no more releases on the 4.9 branch?
> 
> There will be more. https://gcc.gnu.org/ml/gcc/2015-06/msg00163.html

OK. If it hasn't already happened, I think it would be good to back-port that change to 4.9. I guess I should go and read up on the right way to submit that proposal to the maintainers.

Thanks for the responses