Как отключить предупреждение gcc, у которого нет переключателя командной строки?

Я получаю следующее предупреждение:

warning: 'X' is initialized and declared 'extern'

и он выглядит не так уж и страшно, и я могу его отключить. Изменение кода не очень хорошая идея в моем случае, потому что я не имею никакого контроля над кодом, мне просто нужно скомпилировать его. Поэтому я хочу отключить предупреждение.

If it had a -WSomeDefect key next to it then я could use a -Wno-SomeDefect command line switch but it looks like there no distinct switch for this warning.

Если бы рядом с ним была клавиша -WSomeDefect, то я мог бы использовать переключатель командной строки -Wno-SomeDefect, но, похоже, для этого предупреждения нет отдельного переключателя. Как отключить такое предупреждение?

Ответ 1

Для прямого ответа на поставленный вопрос:

Как видно из исходного кода GCC, нет специального переключателя (semi-) для отключения этого предупреждения. Кажется, его можно отключить только путем отключения всех предупреждений (-w) или включения кода, вызывающего сбой, в качестве системного заголовка через -isystem, оба из которых не являются специфичными для подавленных предупреждений.

Существует соответствующий открытый отчет об ошибке в GCC здесь и открытая мета-ошибка для похожих случаев предупреждений без переключателей здесь.

Если вы не хотите использовать два неспецифических механизма подавления, вам, вероятно, придется установить дополнительный флаг в GCC или дождаться исправления ошибок, чтобы отключить это конкретное предупреждение.

Ответ 2

Код, выдающий это предупреждение, недопустим C и должен быть исправлен. Язык C требует выдачи "диагностики" (предупреждений или ошибок) для нарушений ограничений , таких как, и не требует наличия какого-либо способа отключить их. Я полагал (и я подозреваю, что многие другие делают), что extern был нарушением ограничения с инициализатором, поскольку при обычном использовании extern предоставляет только декларацию, а не определение. Тем не менее, согласно 6.9.2 ¶1:

Если объявление идентификатора для объекта имеет область действия файла и инициализатор, объявление является внешним определением для идентификатора.

Поскольку грамматика, по-видимому, допускает extern с инициализатором, это действительно правильное определение.

GCC имеет опцию -w, которая, вероятно, отключит предупреждение, но за счет отключения всех предупреждений без возможности их переопределения и повторного включения. Это имело бы смысл, если бы это было нарушение ограничения, и было бы знаком исправить неверный код; тем не менее, код действителен, и GCC обязательно должен предоставить механизм, чтобы не выдавать ложное предупреждение об этом.

Как отметил Эльяй в комментарии:

Предупреждения бывают нескольких категорий: по стандарту требуется диагностическое сообщение; статический анализ типичного случайного злоупотребления/неправильного использования языка; благонамеренное, но все же стилистическое мнение (например, -Weffc++); возможно, слишком педантичен и/или мелочен (например, -Weverything или -pedantic). В последних категориях должны быть предусмотрены способы отказа от конкретного предупреждения, например, в случае с OP.

В большинстве случаев GCC старается соблюдать это правило, и я думаю, что отсутствие способа его отключения стоило бы сообщать в систему отслеживания ошибок GCC.

Ответ 3

  Существуют сотни экземпляров этого предупреждения, и они заполняют вывод компилятора. Трудно игнорировать.

Если это внешняя библиотека, есть способ уменьшить это предупреждение до одного отчета о конфликте. Я подозреваю, что вы можете жить с одним предупреждением.

Оберните этот библиотечный API своими собственными функциями/методами. Вы можете назвать их 1:1, используя другое пространство имен, чтобы избежать сложной модификации собственного кода, где используется этот API. Таким образом, это предупреждение будет сообщено только тогда, когда включен источник, включающий проблемный заголовочный файл. Цель состоит в том, чтобы включить проблемный заголовочный файл только один раз.

В зависимости от того, как выглядит этот API, это может быть сложнее сделать.

В любом случае, если это сторонняя библиотека, то такой подход облегчит макет этой библиотеки и написание теста для вашего кода.

Ответ 4

Нет никакого специального флага, чтобы отключить это, что, к сожалению, есть, но есть флаг -w, который отключит все предупреждения без возможности их повторного включения.

Из документов GCC:

-w
    Блокировать все предупреждающие сообщения.

Но лучшим вариантом здесь является удаление extern из объявлений/определений переменных. Таким образом, компилятор знает, что переменная определена в модуле перевода. Вы можете связаться с владельцами кода, чтобы узнать, смогут ли они его изменить.