¿Es aconsejable ignorar la advertencia de “gcc-clang”?

Considere el siguiente progtwig:

#include  int main() { std::array x = { 0 }; // warning! x = { { 0 } }; // no warning return 0; } 

La primera inicialización conduce a advertencias en gcc 4.7.2 …

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

… y clang 3.1

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

En lo que respecta al estándar, no debe haber diferencia entre las llaves dobles o simples, al menos en este ejemplo.

Hay dos formas de lidiar con la advertencia:

  1. Solo apágalo
  2. Repara el código, por lo que el comstackdor está feliz

¿Qué propones? En mi humilde opinión, la expresión doble rizado se ve algo feo. Por otro lado, la advertencia podría detectar problemas reales en ejemplos más complicados. ¿Conoces un ejemplo en el que la advertencia te haya ayudado?

-Wmissing-braces ya no estarán habilitadas en la -Wall de GCC -Wall (para el modo C ++), a partir de 4.8, precisamente por la razón que usted describe. Para las versiones actuales de GCC, deshabilite o ignore la advertencia, el código que tiene está escrito como debería.

La advertencia probablemente esté destinada a cubrir código como

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

Sin embargo, en mi humilde opinión, eso ya se maneja lo suficientemente bien con -Wmissing-field-initializers , que no advierte sobre su código original.

Recibo la misma advertencia en Xcode 6.1.1 (la versión actual desde el 9 de marzo de 2015). Cuando agrego llaves adicionales alrededor de cada subobjeto recibo un error. Cuando agrego un conjunto extra de llaves alrededor de toda la lista de inicialización, la advertencia desaparece. De acuerdo con la especificación estándar 14882: 2011 23.3.2.1 [array.overview] subsección 2 declara explícitamente

 array a = { initializer-list }; 

donde initializer-list es una lista separada por comas de hasta N elementos cuyos tipos son convertibles a T

resultado del código en Xcode 6.1.1 (abajo)

 array key1 = {1, 2}; // warning: suggest braces around initialization of subobject array key2 = { {1}, {2} }; // error: no viable overload = array key3 = array { {1}, {2} }; // error: excess elements in struct initializer array key4 = { {1, 2} }; // no warning and no error 

Cuando miramos la subsección 1 de 14882: 2011 8.5 [dcl.init], vemos que una ‘lista de inicializadores’ puede contener opcionalmente una ‘cláusula de inicializador’, que a su vez puede ser una ‘lista-de-inicialización’. Entonces, de cualquier manera, debería ser correcto. Aunque basado en la especificación, personalmente creo que las llaves simples no deberían producir una advertencia de comstackdor para una lista de inicializadores std :: array, y las llaves dobles son excesivas.

Al ignorar la advertencia de Clang con -Wno-missing-braces , recomendaría activar -Wmissing-field-initializers (o usar -Wextra , que también lo incluye). De lo contrario, perderá una advertencia útil como en este ejemplo:

 #include  struct A { int i; int arr[2]; int j; }; void print(const A& a) { printf("i=%d, arr={%d,%d}, j=%d\n", ai, a.arr[0], a.arr[1], aj); } 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) 

A modo de comparación, esto es lo que hace 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}; ^ 

En resumen:

  • Para Clang, recomendaría -Wno-missing-braces -Wmissing-field-initializers para silenciar la advertencia sin perder otras advertencias útiles
  • GCC no se queja en el std::array x = { 0 }; ejemplo, por lo que no es necesario deshabilitar ninguna advertencia. Sin embargo, recomendaría habilitar -Wmissing-field-initializers (o usar -Wextra ), ya que no está habilitado por -Wall .

Clang 6.0 suprime la advertencia sobre llaves faltantes. El registro svn dice:

Suprime la advertencia “Excepto llaves” cuando se inicializa el agregado de una estructura con un solo campo que es en sí mismo un agregado. En C ++, la inicialización de los tipos std :: array está garantizada por el estándar, es completamente idiomática y la alternativa “sugerida” de Clang era técnicamente inválida.

Así que -Wmissing-braces las llaves y desactivaría -Wmissing-braces para Clang antes de 6.0 si necesita ser compatible.