2012-12-16 151 views
41

考虑下面的程序:忽略gcc/clang的“-Wmissing-braces”警告是明智的吗?

#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. 修复代码,所以编译器是幸福

你有什么建议?恕我直言,双卷曲表达看起来有些丑陋。另一方面,这个警告可能会在更复杂的例子中发现真正的问题。你知道一个警告会帮助你的例子吗?

+0

因为std :: array是一个聚合。 看到这个[thread] [1]。 [1]:http://stackoverflow.com/questions/16341118/whats-the-correct-way-to-initialize-a-member-array-with-an-initializer-list –

+0

只是为了告知:为禁用此警告,应该在clang上添加-Wno-missing-括号 –

回答

41

-Wmissing-braces will no longer be enabled in GCC's -Wall (for C++ mode), as of 4.8, for precisely the reason you describe.对于当前版本的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,不警告你原来的代码来处理不够好。

+1

该警告至少涵盖了人们在应该写有'int x [2] [2] = {0}'的C case时写成“{{0}}”。 –

+7

@jørgensen他们为什么要这样做?在C中,“{0}”是适用于所有类型的初始化程序,并且由于此原因而被严格使用。这是完全有效的,这很明显是什么意思,所以为什么要引起警告? – hvd

+0

铿锵仍然警告这个问题,但有一个类似的错误打开,请参阅http://llvm.org/bugs/show_bug.cgi?id=21629 – usr1234567

6

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

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

其中初始化-list是逗号分隔的多达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,我们看到'initializer-list'可以选择性地包含'initializer-clause',它本身可以是'braced-init-list'。所以任何一种方式都应该是正确虽然基于规范,我个人认为单个大括号不应该为std :: array初始化程序列表输出编译器警告,并且双大括号是矫枉过正的。

3

当忽略与-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) 

为了便于比较,这是海湾合作委员会的作用:

$ 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启用的。
+0

你可以在'-Wall'中使用'-Wno-missing-braces'吗?即“除了没有失踪大括号”之外的所有人? –

+0

@DavidDoria是的,你可以 – romeric

2

即将发布的叮当声6.0会压制关于失踪大括号的警告。 svn日志说:

Suppress -Wmissing-braces警告当聚合 - 初始化一个结构与一个单一的领域本身是一个聚合。在C++中,std :: array类型的这种初始化是保证按标准工作,完全是惯用的,并且来自 Clang的“建议”替代在技术上是无效的。

因此,我会省略大括号,并禁用-Wmissing-braces Cla之前6.0。

+1

这很好听。作为参考,这里是声明的来源:https://reviews.llvm.org/rL314838 –