Sé que la pregunta es sobre GCC, pero para las personas que buscan cómo hacer esto en otros y / o compiladores múltiples ...
TL; DR
Es posible que desee echar un vistazo a Hedley , que es un encabezado C / C ++ de dominio público que escribí y que hace muchas de estas cosas por usted. Pondré una sección rápida sobre cómo usar Hedley para todo esto al final de esta publicación.
Deshabilitar la advertencia
#pragma warning (disable: …) tiene equivalentes en la mayoría de los compiladores:
- MSVC:
#pragma warning(disable:4996)
- CCG:
#pragma GCC diagnostic ignored "-W…"donde la elipsis es el nombre de la advertencia; por ejemplo , #pragma GCC diagnostic ignored "-Wdeprecated-declarations.
- tañido:
#pragma clang diagnostic ignored "-W…". La sintaxis es básicamente la misma que la de GCC y muchos de los nombres de advertencia son los mismos (aunque muchos no lo son).
- Compilador Intel C: use la sintaxis MSVC, pero tenga en cuenta que los números de advertencia son totalmente diferentes. Ejemplo:
#pragma warning(disable:1478 1786).
- PGI: Hay un
diag_suppresspragma:#pragma diag_suppress 1215,1444
- TI: Hay un
diag_suppresspragma con la misma sintaxis (¡pero diferentes números de advertencia!) Que PGI:pragma diag_suppress 1291,1718
- Oracle Developer Studio (suncc): hay un
error_messagespragma. Molesto, las advertencias son diferentes para los compiladores C y C ++. Ambos deshabilitan básicamente las mismas advertencias:
- C:
#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
- C ++:
#pragma error_messages(off,symdeprecated,symdeprecated2)
- IAR: también se usa
diag_suppresscomo PGI y TI, pero la sintaxis es diferente. Algunos de los números de advertencia son los mismos, pero otros han divergido:#pragma diag_suppress=Pe1444,Pe1215
- Pelles C: similar a MSVC, aunque nuevamente los números son diferentes
#pragma warn(disable:2241)
Para la mayoría de los compiladores, a menudo es una buena idea verificar la versión del compilador antes de intentar deshabilitarla, de lo contrario, terminará activando otra advertencia. Por ejemplo, GCC 7 agregó soporte para la -Wimplicit-fallthroughadvertencia, así que si te importa GCC antes de 7 deberías hacer algo como
#if defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Para clang y compiladores basados en clang, como las versiones más nuevas de XL C / C ++ y armclang, puede verificar si el compilador conoce una advertencia particular utilizando la __has_warning()macro.
#if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#endif
Por supuesto, también debe verificar si __has_warning()existe la macro:
#if defined(__has_warning)
# if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
# endif
#endif
Puede sentirse tentado a hacer algo como
#if !defined(__has_warning)
# define __has_warning(warning)
#endif
Para que pueda usar __has_warningun poco más fácilmente. Clang incluso sugiere algo similar para la __has_builtin()macro en su manual. No hagas esto . Otro código puede verificar __has_warningy recurrir a verificar las versiones del compilador si no existe, y si usted define __has_warning, romperá su código. La forma correcta de hacer esto es crear una macro en su espacio de nombres. Por ejemplo:
#if defined(__has_warning)
# define MY_HAS_WARNING(warning) __has_warning(warning)
#else
# define MY_HAS_WARNING(warning) (0)
#endif
Entonces puedes hacer cosas como
#if MY_HAS_WARNING(warning)
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#elif defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Empujando y haciendo estallar
Muchos compiladores también admiten una forma de enviar y desplegar advertencias en una pila. Por ejemplo, esto deshabilitará una advertencia en GCC para una línea de código, luego la devolverá a su estado anterior:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
call_deprecated_function();
#pragma GCC diagnostic pop
Por supuesto, no hay mucho acuerdo entre los compiladores sobre la sintaxis:
- GCC 4.6+:
#pragma GCC diagnostic push/#pragma GCC diagnostic pop
- Clang:
#pragma clang diagnostic push/#pragma diagnostic pop
- Intel 13+ (y probablemente anterior):
#pragma warning(push)/#pragma warning(pop)
- MSVC 15+ (VS 9.0 / 2008):
#pragma warning(push)/#pragma warning(pop)
- BRAZO 5.6+:
#pragma push/#pragma pop
- TI 8.1+:
#pragma diag_push/#pragma diag_pop
- Pelles C 2.90+ (y probablemente antes):
#pragma warning(push)/#pragma warning(pop)
Si la memoria funciona, para algunas versiones muy antiguas de GCC (como 3.x, IIRC), los pragmas push / pop tenían que estar fuera de la función.
Ocultando los detalles sangrientos
Para la mayoría de los compiladores es posible ocultar la lógica detrás del uso de macros _Pragma, que se introdujo en C99. Incluso en modo no C99, la mayoría de los compiladores son compatibles _Pragma; La gran excepción es MSVC, que tiene su propia __pragmapalabra clave con una sintaxis diferente. El estándar _Pragmatoma una cadena, la versión de Microsoft no:
#if defined(_MSC_VER)
# define PRAGMA_FOO __pragma(foo)
#else
# define PRAGMA_FOO _Pragma("foo")
#endif
PRAGMA_FOO
Es aproximadamente equivalente, una vez preprocesado, a
#pragma foo
Esto nos permite crear macros para que podamos escribir código como
MY_DIAGNOSTIC_PUSH
MY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated_function();
MY_DIAGNOSTIC_POP
Y esconda todas las verificaciones de versiones feas en las definiciones de macro.
La manera fácil: Hedley
Ahora que comprende la mecánica de cómo hacer cosas como esta de forma portátil mientras mantiene limpio su código, comprende lo que hace uno de mis proyectos, Hedley . En lugar de buscar toneladas de documentación y / o instalar tantas versiones de tantos compiladores como pueda probar, puede incluir Hedley (es un encabezado C / C ++ de dominio público único) y listo. Por ejemplo:
#include "hedley.h"
HEDLEY_DIAGNOSTIC_PUSH
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated();
HEDLEY_DIAGNOSTIC_POP
Deshabilitará la advertencia acerca de llamar a una función obsoleta en GCC, clang, ICC, PGI, MSVC, TI, IAR, ODS, Pelles y posiblemente otras (probablemente no me moleste en actualizar esta respuesta mientras actualizo Hedley). Y, en los compiladores que no se sabe que funcionan, las macros se procesarán previamente a cero, por lo que su código seguirá funcionando con cualquier compilador. Por supuesto, HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATEDno es la única advertencia que Hedley conoce, ni las advertencias de desactivación son todo lo que Hedley puede hacer, pero espero que entiendas la idea.