web-dev-qa-db-fra.com

Comment puis-je me débarrasser des avertissements obsolètes dans les fonctions obsolètes dans GCC?

Une façon d'implémenter des avertissements de dépréciation consiste à générer des avertissements lors d'appels à des fonctions obsolètes, sauf si vous appelez à partir d'un contexte obsolète. De cette façon, le code hérité peut appeler le code hérité sans produire d'avertissements qui ne représentent que du bruit.

C'est une ligne de pensée raisonnable, et elle se reflète dans les implémentations que je vois dans GCC 4.2 (1) et Clang 4.0 (2) sur OS X ainsi que Clang 3.0 (3) sur Ubuntu.

  • (1): i686-Apple-darwin11-llvm-g ++ - 4.2 (GCC) 4.2.1 (Basé sur Apple Inc. build 5658) (LLVM build 2336.11.00)
  • (2): Apple clang version 4.0 (tags/Apple/clang-421.0.57) (basé sur LLVM 3.1svn)
  • (3): Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (basé sur LLVM 3.0)

Cependant, lorsque je compile avec GCC 4.6 (4) sur Ubuntu, j'obtiens des avertissements obsolètes pour toutes les invocations de fonctions obsolètes, indépendamment du contexte. Est-ce une régression des fonctionnalités? Existe-t-il des options de compilation que je peux utiliser pour obtenir l'autre comportement?

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

Exemple de programme:

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
}

Sortie de GCC 4.2 (Oui, je reçois deux fois le même avertissement. Je m'en fiche cependant):

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)

Sortie de 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]

Comment puis-je convaincre GCC 4.6 qu'il devrait me donner la même sortie que GCC 4.2?

29
Magnus Hoff

Le comportement que vous voyez dans GCC 4.2 est causé par un correctif spécifique à Apple pour GCC. FSF GCC 4.2.4 met en garde contre l'utilisation de a. Le bit spécifique que Apple GCC a que FSF GCC n'a pas est:

--- 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));

(Disponible sous GPLv2 ou version ultérieure)

Vous souhaiterez peut-être adapter ce correctif à une version ultérieure de GCC (peut-être qu'aucune modification n'est nécessaire, peut-être des modifications majeures sont nécessaires), et créer GCC à partir de la source avec ce correctif appliqué. Ou vous pouvez signaler cela comme une demande de fonctionnalité sur le bugzilla FSF GCC.

15
user743382

-Wno-deprecated supprimera tous les avertissements obsolètes

40
doron

gcc 4.6 a ajouté des pragmas de diagnostic qui aideront à résoudre ce problème:

#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

Remarque: cela ne fonctionne que dans gcc 4.6 et supérieur. Push et pop sont des extensions 4.6. Avec gcc 4.5, le #pragma GCC diagnostic Push et pop seront ignorés (avec des avertissements). Ce qui ne sera pas ignoré est le #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - mais maintenant cela a effet jusqu'à la fin du fichier.

38
David Hammen

Je rencontre le même problème. La solution qui est apparue est la suivante

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
}

J'ai donc simplement renommé ma classe a en classe OLD_A_NOT_TO_BE_USED. Je reçois l'avertissement uniquement au retour b (); et si quelqu'un utilisait un, il recevra toujours l'avertissement obsolète.

1
wincrasher