Странное диагностическое прагматическое поведение в GCC 4.6 - PullRequest
8 голосов
/ 23 марта 2012

У меня есть программа на Си с парой статических функций, которые (пока) не используются.Я хочу отключить предупреждения для этих конкретных функций.Я не хочу отключать все -Wunused-function предупреждения.Я использую GCC 4.6.В частности:

ek@Apok:~/source$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Я следую совету в документации (чтобы использовать push и pop), но я не смог заставить его работать.

Iсоздали некоторый упрощенный исходный код для исследования проблемы.Я собираю их с gcc -Wall -o pragma pragma.c (где pragma.c).Моя первая версия pragma.c выглядит следующим образом:

void foo(int i) { }
static void bar() { }
int main() { return 0; }

Как и ожидалось, я получаю это при компиляции:

pragma.c:3:13: warning: ‘bar’ defined but not used [-Wunused-function]

Также, как и ожидалось, я могу отключитьпредупреждение вот так (тогда компиляция завершается беззвучно):

#pragma GCC diagnostic ignored "-Wunused-function"
void foo(int i) { }
static void bar() { }
int main() { return 0; }

Но потом я попробовал это:

void foo(int i) { }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static void bar() { }
#pragma GCC diagnostic pop
int main() { return 0; }

Когда я скомпилировал это, я получил оригинальное предупреждение:

pragma.c:4:13: warning: ‘bar’ defined but not used [-Wunused-function]

Удаление pop избавляет от предупреждения:

void foo(int i) { }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static void bar() { }
int main() { return 0; }

Но мне нужен способ отключить предупреждение только для определенного раздела кода.Я не смог этого сделать.

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

Тем не менее, я не могу понять, как это поведение согласуется с документацией, которая говорит, что «прагмы, возникающие после строки, не влияют на диагностику, вызванную этой строкой."

Кто-нибудь знает, что я делаю не так?(Или, если ничего, у кого-то есть дополнительная информация о проблеме, такая как ссылка на отчет об ошибке и / или информация о возможных обходных путях.)

1 Ответ

14 голосов
/ 23 марта 2012

Это работает (gcc версия 4.6.1):

#ifdef __GNUC__
#define SUPPRESS_NOT_USED_WARN __attribute__ ((unused))
#else
#define SUPPRESS_NOT_USED_WARN
#endif

void foo() {  }
SUPPRESS_NOT_USED_WARN static void bar() { }
int main() { return 0; }

/* or
static void SUPPRESS_NOT_USED_WARN bar() { }
 etc. */

/* but not, undefined declarations:
SUPPRESS_NOT_USED_WARN static void bar();
*/

(Изменить :)
GCC v4.2.4 док. 5.32. Задание атрибутов переменных :

не используется
Этот атрибут, прикрепленный к переменной, означает, что переменная, возможно, не используется. GCC не будет выдавать предупреждение для этой переменной.

(Правка.2 :)
GCC v4.2.4 док. 5.25 Объявление атрибутов функций (более правильная ссылка, функции, извините за это.)

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


Когда дело доходит до pragma push и pop и т. Д., В документации говорится:

GCC док. 6.57.10 Диагностические прагмы :

Изменяет расположение диагностики. Обратите внимание, что не все диагностики могут быть изменены; на данный момент можно контролировать только предупреждения (обычно контролируемые `-W ... '), но не все из них. Используйте опцию -fdiagnostics-show-option, чтобы определить, какие диагностики являются управляемыми, а какая опция их контролирует.

В нем говорится; "и не все из них" , -Wunused-function, похоже, один из тех, кто не желает быть подавленным. Опция fdiagnostics-show-option, по-видимому, включена по умолчанию. (Дает флаг, из которого включена ошибка / предупреждение.).

Использование -Wno-unused-function в командной строке отключает его, но, разумеется, для всех, а не только для тех, которые прямо указаны в коде.

Если вы скажете:

gcc -Wunused-function -o o mycode.c

Вы все равно получите предупреждение, - поэтому оно не имеет ничего общего с т. Е. -Wall установкой процесса компиляции в особое состояние, в котором он не будет работать.


В качестве примера это работает:

int foo(int i) { return i; }

int main() {
    int a;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(a);
#pragma GCC diagnostic pop

    return 0;
}
...