c++ - ¿Cómo puedo deshacerme de las advertencias en desuso en funciones en desuso en GCC?
deprecated gcc-warning (4)
Una forma de implementar advertencias de desaprobación es producir advertencias sobre las llamadas a funciones desaprobadas, a menos que esté llamando desde un contexto desaprobado. De esta manera, el código heredado puede llamar al código heredado sin producir advertencias que solo equivalgan a ruido.
Esta es una línea de pensamiento razonable, y se refleja en las implementaciones que veo en GCC 4.2 (1) y Clang 4.0 (2) en OS X, así como en Clang 3.0 (3) en Ubuntu.
- (1): i686-apple-darwin11-llvm-g ++ - 4.2 (GCC) 4.2.1 (basado en Apple Inc. build 5658) (LLVM build 2336.11.00)
- (2): Apple Clang versión 4.0 (tags / Apple / clang-421.0.57) (basado en LLVM 3.1svn)
- (3): Ubuntu clang versión 3.0-6ubuntu3 (tags / RELEASE_30 / final) (basado en LLVM 3.0)
Sin embargo, cuando compilo con GCC 4.6 (4) en Ubuntu, recibo advertencias en desuso para todas las invocaciones de funciones en desuso, independientemente del contexto. ¿Es esta una regresión en funcionalidad? ¿Hay opciones de compilador que puedo usar para obtener el otro comportamiento?
- (4): g ++ (Ubuntu / Linaro 4.6.3-1ubuntu5) 4.6.3
Ejemplo de programa:
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
}
Salida de GCC 4.2 (Sí, recibo la misma advertencia dos veces. Sin embargo, no me importa):
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)
Salida 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]
¿Cómo puedo convencer a GCC 4.6 de que debería darme la misma salida que GCC 4.2?
El comportamiento que está viendo en GCC 4.2 es causado por un parche específico de Apple para GCC. FSF GCC 4.2.4 advierte sobre el uso de a
. El bit específico que tiene Apple GCC que FSF GCC no tiene es:
--- 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 bajo GPLv2 o posterior)
Es posible que desee adaptar este parche a una versión posterior de GCC (quizás no se necesiten cambios, quizás se necesiten cambios importantes), y compilar GCC a partir de la fuente con este parche aplicado. O puede informar de esto como una solicitud de función en FSF GCC bugzilla.
Me encuentro con el mismo problema. La solución que surgió es la siguiente
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
}
Así que simplemente renombro mi clase a OLD_A_NOT_TO_BE_USED class. Solo recibo la advertencia al devolver b (); y si alguien estaba usando un mensaje, todavía recibirán la advertencia desaprobada.
gcc 4.6 agregó pragmas de diagnóstico que ayudarán a resolver este problema:
#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
Nota: Esto solo funciona en gcc 4.6 y superior. El push
y pop
son extensiones 4.6. Con gcc 4.5, se ignorarán #pragma GCC diagnostic push
y pop
#pragma GCC diagnostic push
(con advertencias). Lo que no se ignorará es el #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
, pero ahora esto tiene efecto hasta el final del archivo.
-Wno-deprecated
eliminará todas las advertencias en desuso