proyectos ejemplos c gcc compiler-warnings pragma

c - ejemplos - django



Cómo deshabilitar las advertencias de GCC para unas pocas líneas de código (8)

En Visual C ++, es posible utilizar #pragma warning (disable: ...) . También encontré que en GCC puede anular por banderas de compilador de archivos . ¿Cómo puedo hacer esto para "próxima línea", o con semántica push / pop alrededor de áreas de código usando GCC?


En lugar de silenciar las advertencias, el estilo de gcc suele utilizar construcciones estándar C o la extensión __attribute__ para informar al compilador más acerca de su intención. Por ejemplo, la advertencia sobre la asignación utilizada como condición se suprime colocando la asignación entre paréntesis, es decir, if ((p=malloc(cnt))) lugar de if (p=malloc(cnt)) . Las advertencias sobre los argumentos de las funciones no utilizadas pueden ser suprimidas por algún __attribute__ que nunca recuerdo, o por __attribute__ , etc. Pero generalmente prefiero deshabilitar globalmente cualquier opción de advertencia que genere advertencias sobre cosas que ocurrirán en el código correcto.


Para aquellos que encontraron esta página buscando una manera de hacer esto en IAR, intente esto:

#pragma diag_suppress=Pe177 void foo1( void ) { /* The following line of code would normally provoke diagnostic message #177-D: variable "x" was declared but never referenced. Instead, we have suppressed this warning throughout the entire scope of foo1(). */ int x; } #pragma diag_default=Pe177

Consulte http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124244797.html para referencia.


Para negar todo, este es un ejemplo de desactivación temporal de una advertencia:

#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" write(foo, bar, baz); #pragma GCC diagnostic pop

Puede consultar la documentación de GCC en pragmas de diagnóstico para más detalles.


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:

#pragma GCC diagnostic error "-Wuninitialized" foo(a); /* error is given for this one */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wuninitialized" foo(b); /* no diagnostic for this one */ #pragma GCC diagnostic pop foo(c); /* error is given for this one */ #pragma GCC diagnostic pop foo(d); /* depends on command line options */


Tuve el mismo problema con bibliotecas externas como los encabezados de ROS. Me gusta usar las siguientes opciones en CMakeLists.txt para una compilación más estricta:

set(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Wextra -Wstrict-aliasing -pedantic -Werror -Wunreachable-code ${CMAKE_CXX_FLAGS}")

Sin embargo, hacer esto provoca todo tipo de errores pedantes en bibliotecas incluidas externamente también. La solución es desactivar todas las advertencias pedantes antes de incluir bibliotecas externas y volver a habilitarlas así:

//save compiler switches #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" //Bad headers with problem goes here #include <ros/ros.h> #include <sensor_msgs/LaserScan.h> //restore compiler switches #pragma GCC diagnostic pop


TL; DR : si funciona, evita o usa especificadores como __attribute__ , de lo contrario _Pragma .

Esta es una versión corta de mi artículo de blog Suprimir advertencias en GCC y Clang .

Considere el siguiente Makefile

CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror .PHONY: all all: puts

para construir el siguiente código fuente puts.c

#include <stdio.h> int main(int argc, const char *argv[]) { while (*++argv) puts(*argv); return 0; }

No se compilará porque argc no se -W -Wall -pedantic -Werror y la configuración es hardcore ( -W -Wall -pedantic -Werror ).

Hay 5 cosas que podrías hacer:

  • Mejora el código fuente, si es posible
  • Use un especificador de declaración, como __attribute__
  • Use _Pragma
  • Use #pragma
  • Use una opción de línea de comando.

Mejorando la fuente

El primer intento debería ser verificar si se puede mejorar el código fuente para eliminar 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).

Usar un especificador de declaración, como __attribute__

#include <stdio.h> int main(__attribute__((unused)) int argc, const char *argv[]) { while (*++argv) puts(*argv); return 0; }

Si tiene suerte, el estándar proporciona un especificador para su situación, como _Noreturn .

__attribute__ es una extensión propietaria de GCC (respaldada por Clang y algunos otros compiladores como también por armcc ) y no será comprendida por muchos otros compiladores. Coloque __attribute__((unused)) dentro de una macro si desea un código portable.

_Pragma operador

_Pragma se puede usar como una alternativa a #pragma .

#include <stdio.h> _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored /"-Wunused-parameter/"") int main(int argc, const char *argv[]) { while (*++argv) puts(*argv); return 0; } _Pragma("GCC diagnostic pop") /

La principal ventaja del operador _Pragma es que puede colocarlo dentro de las macros, lo que no es posible con la directiva #pragma .

Desventaja: es casi una bomba nuclear táctica, ya que funciona en línea en lugar de declaración-baesd.

El operador _Pragma se introdujo en C99.

directiva #pragma .

Podríamos cambiar el código fuente para suprimir la advertencia de una región de código, generalmente una función completa:

#include <stdio.h> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" int main(int argc, const char *argv[]) { while (*++argc) puts(*argv); return 0; } #pragma GCC diagnostic pop

Desventaja: es casi una bomba nuclear táctica, ya que funciona en línea en lugar de declaración-baesd.

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 puts:

CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror .PHONY: all all: puts puts.o: CPPFLAGS+=-Wno-unused-parameter

Probablemente no sea esto lo que quiere en su caso particular, pero puede ayudar a otras personas que se encuentran en situaciones similares.


#define DIAG_STR(s) #s #define DIAG_JOINSTR(x,y) DIAG_STR(x ## y) #ifdef _MSC_VER #define DIAG_DO_PRAGMA(x) __pragma (#x) #define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(warning(x)) #else #define DIAG_DO_PRAGMA(x) _Pragma (#x) #define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(compiler diagnostic x) #endif #if defined(__clang__) # define DISABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,push) DIAG_PRAGMA(clang,ignored DIAG_JOINSTR(-W,clang_option)) # define ENABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,pop) #elif defined(_MSC_VER) # define DISABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,push) DIAG_DO_PRAGMA(warning(disable:##msvc_errorcode)) # define ENABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,pop) #elif defined(__GNUC__) #if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 # define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,push) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option)) # define ENABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,pop) #else # define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option)) # define ENABLE_WARNING(gcc_option,clang_option,msvc_unused) DIAG_PRAGMA(GCC,warning DIAG_JOINSTR(-W,gcc_option)) #endif #endif

Esto debería ser el truco para gcc, clang y msvc

Se puede llamar con, por ejemplo:

DISABLE_WARNING(unused-variable,unused-variable,42) [.... some code with warnings in here ....] ENABLE_WARNING(unused-variable,unused-variable,42)

consulte 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 está seguro acerca de msvc y clang sobre las versiones.

Parece que el manejo del empuje pop pragma para gcc está un poco roto. Si habilita nuevamente la advertencia, aún recibirá la advertencia para el bloque que estaba dentro del bloque DISABLE_WARNING / ENABLE_WARNING. Para algunas versiones de gcc funciona, para algunos no funciona.


#pragma GCC diagnostic ignored "-Wformat"

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.