En Visual C ++, es posible usarlo #pragma warning (disable: ...)
. También descubrí que en GCC puede anular las banderas del compilador por archivo . ¿Cómo puedo hacer esto para la "línea siguiente", o con semántica push / pop alrededor de áreas de código usando GCC?
c
gcc
compiler-warnings
pragma
Matt Joiner
fuente
fuente
Respuestas:
Parece que esto se puede hacer . No puedo determinar la versión de GCC que se agregó, pero fue en algún momento antes de junio de 2010.
Aquí hay un ejemplo:
fuente
push
y dospop
s - puede ser otropush
al principio falta?Para eliminar todo, este es un ejemplo de deshabilitar temporalmente una advertencia:
Puede consultar la documentación de GCC sobre pragmas de diagnóstico para obtener más detalles.
fuente
gcc-4.9
solo ignora esta línea por completo.TL; DR : si funciona, evite o use especificadores como
__attribute__
, de lo contrario_Pragma
.Esta es una versión corta del artículo de mi blog Suprimir advertencias en GCC y Clang .
Considera lo siguiente
Makefile
para construir el siguiente
puts.c
código fuenteNo se compilará porque
argc
no se usa, y la configuración es hardcore (-W -Wall -pedantic -Werror
).Hay 5 cosas que puedes hacer:
__attribute__
_Pragma
#pragma
Mejorando la fuente
El primer intento debe ser verificar si el código fuente se puede mejorar para deshacerse de la advertencia. En este caso, no queremos cambiar el algoritmo solo por eso, ya que
argc
es redundante con!*argv
(NULL
después del último elemento).Usando un especificador de declaración, como
__attribute__
Si tiene suerte, el estándar proporciona un especificador para su situación, como
_Noreturn
.__attribute__
es una extensión patentada de GCC (también compatible con Clang y algunos otros compiladoresarmcc
) y muchos otros compiladores no la entenderán. Poner__attribute__((unused))
dentro de una macro si quieres un código portátil._Pragma
operador_Pragma
se puede usar como una alternativa a#pragma
.La principal ventaja del
_Pragma
operador es que puede colocarlo dentro de macros, lo cual no es posible con la#pragma
directiva.Desventaja: es casi un arma nuclear táctica, ya que funciona en línea en lugar de en la declaración.
El
_Pragma
operador se introdujo en C99.#pragma
directiva.Podríamos cambiar el código fuente para suprimir la advertencia de una región de código, generalmente una función completa:
Desventaja: es casi un arma nuclear táctica, ya que funciona en línea en lugar de en la declaración.
Tenga en cuenta que existe una sintaxis similar en clang .
Suprimir la advertencia en la línea de comando para un solo archivo
Podríamos agregar la siguiente línea al
Makefile
para suprimir la advertencia específicamente para los put:Probablemente no sea lo que quiere en su caso particular, pero puede ayudar a otras lecturas que se encuentran en situaciones similares.
fuente
improving the source
también funcionaría cambiar la declaración de main alint main(int, const char* argv[]) { ... }
no darle un nombre al argumento, le dice al compilador que no se usará.gcc
, así comoclang
.#define UNUSED(x) ((void)x)
utilizada para silenciar advertencias. Creo que fue en ReactOS?_Pragma("GCC diagnostic pop") \
debería ser_Pragma("GCC diagnostic pop")
, creo.Esto debería hacer el truco para gcc, clang y msvc
Se puede llamar con, por ejemplo:
ver https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html , http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas y https://msdn.microsoft .com / de-DE / library / d9x1s805.aspx para más detalles
Necesita al menos la versión 4.02 para usar este tipo de pragmas para gcc, no estoy seguro acerca de msvc y clang acerca de las versiones.
Parece que el manejo del pragma push pop para gcc está un poco roto. Si habilita la advertencia nuevamente, aún obtiene la advertencia para el bloque que estaba dentro del bloque DISABLE_WARNING / ENABLE_WARNING. Para algunas versiones de gcc funciona, para algunas no.
fuente
Reemplace "-Wformat" con el nombre de su bandera de advertencia.
AFAIK no hay forma de usar la semántica push / pop para esta opción.
fuente
Tuve el mismo problema con las bibliotecas externas como los encabezados ROS. Me gusta usar las siguientes opciones en CMakeLists.txt para una compilación más estricta:
Sin embargo, hacer esto también causa todo tipo de errores pedantes en bibliotecas incluidas externamente. La solución es desactivar todas las advertencias pedantes antes de incluir bibliotecas externas y volver a habilitarlas así:
fuente
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:#pragma warning(disable:4996)
#pragma GCC diagnostic ignored "-W…"
donde la elipsis es el nombre de la advertencia; por ejemplo ,#pragma GCC diagnostic ignored "-Wdeprecated-declarations
.#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).#pragma warning(disable:1478 1786)
.diag_suppress
pragma:#pragma diag_suppress 1215,1444
diag_suppress
pragma con la misma sintaxis (¡pero diferentes números de advertencia!) Que PGI:pragma diag_suppress 1291,1718
error_messages
pragma. Molesto, las advertencias son diferentes para los compiladores C y C ++. Ambos deshabilitan básicamente las mismas advertencias:#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
#pragma error_messages(off,symdeprecated,symdeprecated2)
diag_suppress
como 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
#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-fallthrough
advertencia, así que si te importa GCC antes de 7 deberías hacer algo comoPara 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.Por supuesto, también debe verificar si
__has_warning()
existe la macro:Puede sentirse tentado a hacer algo como
Para que pueda usar
__has_warning
un 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_warning
y 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:Entonces puedes hacer cosas como
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:
Por supuesto, no hay mucho acuerdo entre los compiladores sobre la sintaxis:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
#pragma clang diagnostic push
/#pragma diagnostic pop
#pragma warning(push)
/#pragma warning(pop)
#pragma warning(push)
/#pragma warning(pop)
#pragma push
/#pragma pop
#pragma diag_push
/#pragma diag_pop
#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__pragma
palabra clave con una sintaxis diferente. El estándar_Pragma
toma una cadena, la versión de Microsoft no:Es aproximadamente equivalente, una vez preprocesado, a
Esto nos permite crear macros para que podamos escribir código como
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:
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_DEPRECATED
no 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.fuente
En lugar de silenciar las advertencias, el estilo gcc generalmente es usar construcciones C estándar o la
__attribute__
extensión para contarle al compilador más sobre su intención. Por ejemplo, la advertencia sobre la asignación utilizada como condición se suprime al poner la asignación entre paréntesis, es decir, enif ((p=malloc(cnt)))
lugar deif (p=malloc(cnt))
. Las advertencias sobre argumentos de funciones no utilizadas pueden ser suprimidas por alguna extraña__attribute__
que nunca recuerdo, o por autoasignación, etc. Pero generalmente prefiero simplemente deshabilitar globalmente cualquier opción de advertencia que genere advertencias para cosas que ocurrirán en el código correcto.fuente
if ((p=malloc(cnt)) != NULL) ...
que eso es lo que el compilador está haciendo detrás de escena.Para aquellos que encontraron esta página buscando una manera de hacer esto en IAR, intente esto:
Consulte http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124244797.html como referencia.
fuente