Are curly braces needed around initialization?

According to GCC 4.6.3 (Ubuntu / Linaro 4.6.3-1ubuntu5) I miss the curly brace in initializing the array in the following code:

#include <iostream> #include <boost/array.hpp> #include <array> int main(){ int plain[] = {1,2,3,4,5}; std::array <int, 5> std_arr = {1,2,3,4,5}; // warning, see below boost::array<int, 5> boost_arr = {1,2,3,4,5}; // warning, see below std::cout << plain[0] << std_arr[1] << boost_arr[2] << std::endl; } 
  > g ++ test.cc -Wall -Wextra -pedantic --std = c ++ 0x                                                                                  
 test.cc: in function "int main ()":
 test.cc:7:47: warning: curly braces missing around initialization for "std :: array :: value_type [5] {aka int [5]}" [-Wmissing-braces]
 test.cc:8:47: warning: curly braces missing around initialization for "int [5]" [-Wmissing-braces] 

Apparently ( GCC was missing bindings around the initializer ), this is a bug in GCC, even in a slightly different context. Responses differ from the "error message file" to "just disable the warning."

However, in the context of std::array or boost::array , is this warning unnecessary, or am I missing something important?

(I will probably add extra curly braces instead of turning off the warning, but I'm curious what the consequences are)

+6
source share
3 answers

I think this is already answered here .

std :: array is funny. It is defined mainly as follows:

template struct std :: array {T a [size]; };

This is the structure containing the array. It does not have a constructor that accepts a list of initializers. But std :: array is a collection of C ++ 11 rules, and therefore it can be created by aggregating initialization. To aggregate the initialization of an array inside a structure, you will need a second set of curly braces:

std :: array strings = {{"a", "b"}};

Please note that the standard assumes that additional braces may be in this case. This is probably a GCC bug.

I believe that this may be due to this defect , which was connected in several issues.

Here answer it :

However, these additional curly braces can only be canceled "in the declaration form T x = {a};" (C ++ 11 ยง8.5.1 / 11), that is, when the old style = is used. This rule, which allows alignment of shapes, is not used to directly initialize a list. The footnote here says: "Brackets cannot be deleted for other purposes of using list initialization."

There is a defect report regarding this limitation: defect CWG # 1270. If the adopted proposed resolution is adopted, then alignment of figures will be allowed for other forms of list initialization, ...

I noticed that the error does not appear in gcc 4.8.1, but it works in a very old version (4.4.7), and I think this is a patch (because the problem the decision is dated February 2012, and this link is dated March 2012):

http://gcc.gnu.org/ml/gcc-patches/2012-03/msg00215.html

+5
source

This is an annoying security warning that was introduced in one of the earlier versions of GCC for both C and C ++ initializers. If I remember correctly, it precedes C ++ 11 and is not actually associated with C ++ 11 (again, it affects C as much as it does with C ++). Basically, for initialization for each nested aggregate an additional level of nested {} is required. Language does not require this, so this is just a warning.

The warning in question may be useful in many cases, but the implementation has been poorly thought out. One completely ridiculous consequence of this warning is that it "kills" the initialization idiom = { 0 } in C. (In C, you can initialize with = { 0 } , but because of this annoying warning, you are forced to selectively use such things like = {{0}} , = {{{0}}} , etc.).

In C ++ std::array class is a collection for which initializers = { ... } handled by the friendly aggregate initialization of the aggregate, rather than by a dedicated constructor. (In C ++ 11, aggregation initialization rules were rewritten in terms of initializer lists, but the general behavior of the C style was intentionally preserved by the ability to eliminate it from the side.) For this reason, std::array also affects this initialization, std::array - it is a collection containing the actual array, which is also a collection. For this reason, to jump to the elements of an array in the initializer, GCC recommends that you open two levels {} .

So, with std::array you just found another example of when this warning does more harm than good.

+3
source

No, there really is no way that a reasonable compiler can ruin this, for a class it's simple.

+2
source

Source: https://habr.com/ru/post/959398/


All Articles