2

Let's consider this code:

#include <vector>
#include <array>

int main()
{
    std::vector<std::array<int, 3>> arr;
    
    arr.push_back({ 1,2,3});          // WARNING
    arr.push_back({{4,5,6}});         // All good
    
    std::array<int, 3> a1 {1,1,1};    // WARNING
    std::array<int, 3> a2 {{2,2,2}};  // All good
    std::vector<int>   a3 {3,3,3};    // All good
    std::vector<int>   a4 {{4,4,4}};  // All good

    return 0;
}

Everything compiles correctly, and all the vector & arrays contain elements as expected.

However, when using flag -Wmissing-braces in gcc (tested with 10.2) we get:

<source>:8:27: warning: missing braces around initializer for 'std::__array_traits<int, 3>::_Type' {aka 'int [3]'} [-Wmissing-braces]
    8 |     arr.push_back({ 1,2,3});          // WARNING
   11 |     std::array<int, 3> a1 {1,1,1};    // WARNING

Why is gcc showing this warning? Is this a bug as per https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 or https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80454 as suggested in How to repair warning: missing braces around initializer?, or is there genuinely something wrong with the 2 marked lines above?

Phil-ZXX
  • 2,359
  • 2
  • 28
  • 40

1 Answers1

1

Those bug reports are about unhelpfully issuing the warning for the special case {0}, which is valid for initializing any struct type in C and thus sometimes must be used because such a type is left unspecified.

This code is correct as given; the warning is just the usual result of std::array<T,N> having to contain a member of type T[N], so that additional braces are required if you want to explicitly initialize every level (and sometimes if other brace initialization is in use). If you ask your compiler to be pedantic about such things with -Wmissing-braces, it does what you asked and warns about the shorthand. (std::vector<int> doesn’t need extra braces because it’s using an initializer-list constructor, not aggregate initialization.)

Davis Herring
  • 36,443
  • 4
  • 48
  • 76
  • So when you say `unhelpfully issuing the warning for the special case {0}`, doesn't that mean the warning could be seen as a bug? – Phil-ZXX Feb 27 '21 at 16:12
  • @Phil-ZXX: Yes, and it’s been reported as such (twice at least), but that’s not your question, is it? You didn’t use `{0}`. – Davis Herring Feb 27 '21 at 18:30
  • My question is if the warning displayed at e.g. `arr.push_back({1,2,3});` is a valid warning. And if not, why does gcc show it (and is this warning a bug then)? – Phil-ZXX Feb 27 '21 at 18:36
  • @Phil-ZXX: Of course that’s your question; you stated it clearly in the first place. Moreover, I’ve answered it. – Davis Herring Feb 27 '21 at 18:42
  • I am still not sure I fully understand your answer. On the one hand "This code is correct as given" and on the other "additional braces are required to explicitly initialize every level". So how can the code be correct while additional braces are required? If the code was indeed correct, there should be no warning, no? – Phil-ZXX Feb 27 '21 at 18:48
  • @Phil-ZXX: If the code were (known by the compiler to be) wrong, it would be an error, not a warning. Warnings are for code that is allowed but is *suspected* to be incorrect, either because it doesn’t do what a casual observer might expect or because it might have undefined behavior. It’s inherently heuristic in some cases, so there exists code like this where the programmer isn’t wrong to write it (unless you want to be pedantic, which is what the warning flag means) but neither is the compiler wrong to warn about it. – Davis Herring Feb 27 '21 at 20:27