0

Стоит ли игнорировать предупреждение "-Wmissing-braces" от gcc/clang?

9

Описание проблемы:

Рассмотрим следующую программу:

#include <array>

int main()
{
  std::array<int, 1> x = { 0 }; // предупреждение!
  x = { { 0 } }; // без предупреждения
  return 0;
}

Первичная инициализация приводит к предупреждениям в gcc 4.7.2:

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

... и в clang 3.1:

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

Согласно стандарту, не должно быть никакой разницы между одинарными и двойными фигурными скобками, по крайней мере в данном примере.

Существует два способа справиться с предупреждением:

  1. Просто отключить его.
  2. Исправить код, чтобы компилятор не вызывал предупреждений.

Что вы предлагаете? На мой взгляд, использование двойных фигурных скобок выглядит несколько неаккуратно. С другой стороны, данное предупреждение может помочь обнаружить настоящие проблемы в более сложных примерах. Знаете ли вы пример, в котором это предупреждение могло бы вам помочь?

2 ответ(ов)

0

У меня такая же проблема в Xcode 6.1.1 (текущая версия на 9 марта 2015 года). Когда я добавляю дополнительные фигурные скобки вокруг каждого подобъекта, возникает ошибка. Когда же я добавляю дополнительный набор фигурных скобок вокруг всего списка инициализации, предупреждение исчезает. Согласно стандартной спецификации 14882:2011, раздел 23.3.2.1 [array.overview], пункт 2 явно указывает:

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

где initializer-list - это запятая-разделенный список до N элементов, типы которых могут быть преобразованы в T.

Вот результат выполнения кода в Xcode 6.1.1 (ниже):

array<int, 2> key1 = {1, 2}; // предупреждение: предложены скобки вокруг инициализации подобъекта

array<int, 2> key2 = { {1}, {2} }; // ошибка: нет подходящей перегрузки =

array<int, 2> key3 = array<int, 2> { {1}, {2} }; // ошибка: лишние элементы в инициализаторе структуры

array<int, 2> key4 = { {1, 2} }; // без предупреждений и ошибок

Если взглянуть на 14882:2011, раздел 8.5 [dcl.init], пункт 1, мы увидим, что 'initializer-list' может опционально содержать 'initializer-clause', которая сама по себе может быть 'braced-init-list'. Поэтому оба варианта должны работать корректно. Однако, основываясь на спецификации, я лично считаю, что одиночные скобки не должны вызывать предупреждение компилятора для списка инициализации std::array, а двойные скобки - излишни.

0

В Clang 6.0 было принято решение подавлять предупреждение о пропущенных фигурных скобках (-Wmissing-braces) при инициализации структур, содержащих единственное поле, которое само является агрегатом. Об этом упоминается в логе SVN:

"Подавить предупреждение -Wmissing-braces, когда инициализируется структура с одним полем, которая сама является агрегатом. В C++ такая инициализация типов std::array гарантированно работает согласно стандарту, она полностью идиоматична, а 'предлагаемая' альтернатива от Clang была технически недействительной."

Таким образом, если вам необходимо поддерживать версии Clang до 6.0, вы можете просто опустить фигурные скобки и отключить предупреждение -Wmissing-braces.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь