忽视gcc/clang的"-Wmissing-braces"警告是明智的吗?

Phi*_*ßen 47 c++ compiler-warnings c++11

考虑以下程序:

#include <array>

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

第一次初始化导致gcc 4.7.2上的警告......

main.cpp:5:22: warning: unused variable ‘x’ [-Wunused-variable]
Run Code Online (Sandbox Code Playgroud)

......和铿锵3.1

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

就标准而言,双花键或单花括号之间应该没有区别,至少在这个例子中.

有两种方法可以处理警告:

  1. 把它关掉
  2. 修复代码,编译器很高兴

你有什么建议?恕我直言,双卷曲表达看起来有些难看.另一方面,警告可能会在更复杂的示例中检测到实际问题.你知道这个警告对你有帮助的例子吗?

小智 46

-Wmissing-braces-Wall由于您描述的原因,将不再在GCC (用于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
};
Run Code Online (Sandbox Code Playgroud)

但是,恕我直言,已经处理得很好-Wmissing-field-initializers,没有警告你的原始代码.

  • @jørgensen他们为什么要这样?在C中,`{0}`是适用于所有类型的初始化程序,并且由于这个原因而被使用得非常严格.这是完全有效的,它显然意味着什么,为什么要引起警告呢? (9认同)

Rob*_*dge 8

我在Xcode 6.1.1(截至2015年3月9日的当前版本)中收到相同的警告.当我在每个子对象周围添加额外的大括号时,我收到错误.当我在整个初始化列表周围添加一组额外的大括号时,警告就会消失.根据标准规范14882:2011 23.3.2.1 [array.overview]第2小节明确说明

array<T, N> a = { initializer-list };
Run Code Online (Sandbox Code Playgroud)

其中initializer-list是一个逗号分隔的列表,最多包含N个元素,其类型可转换为T.

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
Run Code Online (Sandbox Code Playgroud)

当我们查看14882:2011 8.5 [dcl.init]第1小节时,我们看到'initializer-list'可以选择包含'initializer-clause',它本身可以是'braced-init-list'.所以两种方式都应该是正确的.虽然基于规范我个人认为单个大括号不应该输出std :: array initializer-list的编译器警告,而双括号是过度的.


pro*_*ski 5

Clang 6.0 抑制了有关缺少大括号的警告。svn 日志显示:

当聚合初始化具有本身就是聚合的单个字段的结构时,抑制 -Wmissing-braces 警告。在 C++ 中,std::array 类型的这种初始化保证可以按照标准工作,完全符合惯用语,并且 Clang 的“建议”替代方案在技术上是无效的。

-Wmissing-braces因此,如果需要支持,我会省略大括号并禁用6.0 之前的 Clang。