Как я могу избавиться от устаревших предупреждений в устаревших функциях в GCC?

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

Это разумное мышление, и оно отражено в реализациях, которые я вижу в GCC 4.2 (1) и Clang 4.0 (2) в OS X, а также в Clang 3.0 (3) в Ubuntu.

  • (1): i686-apple-darwin11-llvm-g ++ — 4.2 (GCC) 4.2.1 (на основе Apple Inc., сборка 5658) (LLVM, сборка 2336.11.00)
  • (2): Apple clang версии 4.0 (теги / Apple / clang-421.0.57) (на основе LLVM 3.1svn)
  • (3): Ubuntu clang версии 3.0-6ubuntu3 (tags / RELEASE_30 / final) (на основе LLVM 3.0)

Однако, когда я компилирую с GCC 4.6 (4) в Ubuntu, я получаю устаревшие предупреждения для всех вызовов устаревших функций, независимо от контекста. Это регрессия в функциональности? Есть ли варианты компилятора, которые я могу использовать, чтобы получить другое поведение?

  • (4): g ++ (Ubuntu / Linaro 4.6.3-1ubuntu5) 4.6.3

Пример программы:

int __attribute__((deprecated)) a() {
return 10;
}

int __attribute__((deprecated)) b() {
return a() * 2; //< I want to get rid of warnings from this line
}

int main() {
return b(); //< I expect a warning on this line only
}

Вывод из GCC 4.2 (Да, я получаю одно и то же предупреждение дважды. Впрочем, мне все равно):

main.cpp: In function ‘int main()’:
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5)
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5)

Выход из GCC 4.6:

main.cpp: In function 'int b()':
main.cpp:6:9: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations]
main.cpp:6:11: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations]
main.cpp: In function 'int main()':
main.cpp:10:9: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations]
main.cpp:10:11: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations]

Как я могу убедить GCC 4.6, что он должен дать мне тот же вывод, что и GCC 4.2?

25

Решение

Поведение, которое вы видите в GCC 4.2, вызвано специфичным для Apple патчем для GCC. FSF GCC 4.2.4 предупреждает об использовании a, Конкретный бит, который имеет Apple GCC, которого нет у FSF GCC:

--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -902,6 +902,9 @@ warn_deprecated_use (tree node)
if (node == 0 || !warn_deprecated_decl)
return;

+  if (current_function_decl && TREE_DEPRECATED (current_function_decl))
+    return;
+
if (DECL_P (node))
{
expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (node));

(Доступно под GPLv2 или новее)

Возможно, вы захотите адаптировать этот патч к более поздней версии GCC (возможно, никаких изменений не требуется, возможно, необходимы значительные изменения), и собрать GCC из исходного кода с применением этого патча. Или вы можете сообщить об этом как запрос функции на bugzilla FSF GCC.

13

Другие решения

В gcc 4.6 добавлены диагностические прагмы, которые помогут решить эту проблему:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"int __attribute__((deprecated)) b() {
return a() * 2; //< I want to get rid of warnings from this line
}
#pragma GCC diagnostic pop

Примечание: это работает только в gcc 4.6 и выше. push а также pop 4,6 расширения. С gcc 4.5, #pragma GCC diagnostic push а также pop будет игнорироваться (с предупреждениями). Что не будет проигнорировано, так это #pragma GCC diagnostic ignored "-Wdeprecated-declarations" — но теперь это действует до конца файла.

34

-Wno-deprecated удалит все устаревшие предупреждения

32

Я сталкиваюсь с той же проблемой. Решение, которое пришло, заключается в следующем

typedef OLD_A_NOT_TO_BE_USED a __attribute__((deprecated));

int OLD_A_NOT_TO_BE_USED () {
return 10;
}

int __attribute__((deprecated)) b() {
return OLD_A_NOT_TO_BE_USED () * 2; //< I want to get rid of warnings from this line
}

int main() {
return b(); //< I expect a warning on this line only
}

Поэтому я просто переименую свой класс в класс OLD_A_NOT_TO_BE_USED. Я получаю предупреждение только по возвращении b (); и если кто-то использовал, они все равно получат устаревшее предупреждение.

1
По вопросам рекламы [email protected]