它是明智的,忽略的gcc /铿锵的“-Wmissing-括号”的警告?(Is it wise to

2019-07-05 11:53发布

考虑下面的程序:

#include <array>

int main()
{
  std::array<int, 1> x = { 0 }; // warning!
  x = { { 0 } }; // no warning
  return 0;
}

首先初始化导致警告在GCC 4.7.2 ...

main.cpp:5:22: warning: unused variable ‘x’ [-Wunused-variable]

......铛和3.1

main.cpp:5:28: warning: suggest braces around initialization of subobject [-Wmissing-braces]
  std::array<int, 1> x = { 0 };

至于标准推移,应该有至少在该示例双或单花括号之间没有区别,。

有两种方法来处理警告:

  1. 只需将其关闭
  2. 修复了代码,所以编译器是幸福的

你有什么建议? 恕我直言,双卷曲的表情看起来有点丑。 在另一方面,警告可能会检测到更复杂的例子实际问题。 你知道的警告会帮助你的例子吗?

Answer 1:

-Wmissing-braces将不再在GCC的启用-Wall (对于C ++模式),为4.8,为您精确描述的原因。 对于现有版本的gcc,禁用或忽略警告,您可以编写代码的方式是应该的。

警告可能是用来支付代码,如

struct A { int a; int b; };
struct B { A a; int b; };
B b = {
  1,
  2 // initialises b.a.b, not b.b
};

但是,恕我直言,这已经被处理的不够好-Wmissing-field-initializers ,它不会警告你的原代码。



Answer 2:

我得到在Xcode 6.1.1(目前版本为2015年3月9日的)相同的警告。 当我周围添加的每个子对象的额外括号我得到一个错误。 当我添加一个额外的一套围绕整个初始化列表括号,然后报警消失。 根据标准规范14882:2011 23.3.2.1 [array.overview]第2明确规定

array<T, N> a = { initializer-list };

其中初始化-list是逗号分隔的,其类型是转换为T多达N个元素的列表

在Xcode 6.1.1(下文)的结果的代码

array<int, 2> key1 = {1, 2}; // warning: suggest braces around initialization of subobject

array<int, 2> key2 = { {1}, {2} }; // error: no viable overload =

array<int, 2> key3 = array<int, 2> { {1}, {2} }; // error: excess elements in struct initializer

array<int, 2> key4 = { {1, 2} }; // no warning and no error

当我们在14882:2011 8.5 [dcl.init]第1我们看到,一个“初始化列表”可任选地包含一个“初始化子句”,其本身可以是一个“支撑-INIT列表”。 所以,无论哪种方式,应该是正确的。 尽管基于规范我个人认为单括号不应该输出编译器警告为一个std ::阵列初始化列表,以及双括号是矫枉过正。



Answer 3:

锵6.0抑制失踪括号警告。 在SVN的日志说:

抑制-Wmissing拉条时,总初始化与单个字段本身就是一个聚集体结构的警告。 在C ++中,标准::数组类型的这种初始化保证由标准工作,完全是惯用的,而“建议”从锵替代在技术上是无效。

所以我省略了括号和禁用-Wmissing-braces为锵之前6.0是否需要支持。



Answer 4:

当忽略锵与警告-Wno-missing-braces ,我会建议,以使-Wmissing-field-initializers (或使用-Wextra ,其中还包括它)。 否则,你会错过就像这个例子很有用的警告:

#include <cstdio>

struct A
{
  int i;
  int arr[2];
  int j;
};

void print(const A& a)
{
  printf("i=%d, arr={%d,%d}, j=%d\n", a.i, a.arr[0], a.arr[1], a.j);
}

int main() {
  A a = {1, 2, 3}; // this is the critical line
  print(a); // output: i=1, arr={2,3}, j=0

  A b = {1, {2}, 3};
  print(b); // output: i=1, arr={2,0}, j=3

  A c = {1, {2,0}, 3};
  print(c); // output: i=1, arr={2,0}, j=3

  return 0;
}
$ clang++ -Wall example.cpp
example.cpp:16:13: warning: suggest braces around initialization of
      subobject [-Wmissing-braces]
  A a = {1, 2, 3};
            ^~~~
            {   }
1 warning generated.

$ clang++ -Wall -Wno-missing-braces example.cpp
(no warnings)

$ clang++ -Wall -Wno-missing-braces -Wmissing-field-initializers example.cpp
example.cpp:16:17: warning: missing field 'j' initializer
      [-Wmissing-field-initializers]
  A a = {1, 2, 3};
                ^
1 warning generated.

$ clang++ --version
clang version 3.8.1 (tags/RELEASE_381/final)

为了便于比较,这是GCC的作用:

$ g++ -Wall -Wextra example.cpp
(no warning)

$ g++ -Wall -Wmissing-field-initializers example.cpp
example.cpp: In function ‘int main()’
example.cpp:16:17: warning: missing initializer for member ‘A::j’ [-Wmissing-field-initializers]
   A a = {1, 2, 3};
                 ^

综上所述:

  • 对于铛,我会建议-Wno-missing-braces -Wmissing-field-initializers沉默的警告没有松动的其他有用的警告
  • GCC不原来在抱怨std::array<int, 1> x = { 0 }; 例如,所以没有必要禁止任何警告。 不过,我会建议,以使-Wmissing-field-initializers (或使用-Wextra ),因为它不会被启用-Wall


文章来源: Is it wise to ignore gcc/clang's “-Wmissing-braces” warning?