Подтвердить что ты не робот

Как я могу избавиться от устаревших предупреждений в устаревших функциях в 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. build 5658) (LLVM build 2336.11.00)
  • (2): Apple clang version 4.0 (теги/Apple/clang-421.0.57) (на основе LLVM 3.1svn)
  • (3): Ubuntu clang version 3.0-6ubuntu3 (теги/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?

4b9b3361

Ответ 1

Поведение, которое вы видите в 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 из источника с использованием этого патча. Или вы можете сообщить об этом как запрос функции на FSG GCC bugzilla.

Ответ 2

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

Ответ 3

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", но теперь это действует до конца файла.

Ответ 4

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

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(); и если кто-то использует их, они все равно получат устаревшее предупреждение.