2012-12-16 164 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 –