¿Cómo deshabilitar las advertencias para archivos de inclusión en particular?

78

Me gustaría deshabilitar advertencias particulares para todos los archivos que se incluyen, directa o indirectamente, por archivos de inclusión en particular. Por ejemplo, quiero desactivar la advertencia "estás asignando un literal de cadena a un carácter *", para todos los archivos o archivos incluidos por archivos incluidos por a #include <bar/*>(la estrella en mi caso significa "cualquier cosa puede estar aquí").

La razón es que algunas de las personas con las que tengo que programar simplemente no pueden usar "const", así que al final recibo muchas advertencias sobre ese abuso literal de cadena en particular. Me gustaría ignorar esos miles de advertencias que provienen de su código, para poder concentrarme en los errores en mi propio código y corregirlos.

Utilizo Intel C ++ y GCC. Algunos de mis amigos usan clang, por lo que también me alegraría escuchar soluciones para eso.

Johannes Schaub - litb
fuente
¿Lo estoy entendiendo bien? Si un archivo en cuestión está incluido en <bar/the_file.h>, las advertencias deben suprimirse, ¿y <the_file.h>no?
Xeo
@Neil gracias por los enlaces relacionados. Solo para dejar en claro a los demás que pueden tener algunas asociaciones no deseadas: ¡Los dos enlaces anteriores no son enlaces engañosos!
Johannes Schaub - litb
@Xeo no eso en particular. Puedo vivir con todas las advertencias deshabilitadas para ese archivo. No es necesario que tenga un patrón de inclusión específico. Sospecho que la forma en que formulé mi pregunta es un poco desafortunada.
Johannes Schaub - litb
Qué compilador estas usando? (Métodos de la supresión de advertencias a menudo difieren por compilador.)
Ben Hocking

Respuestas:

71

Al usar GCC, puede usar la -isystembandera en lugar de la -Ibandera para deshabilitar las advertencias de esa ubicación.

Entonces, si está usando actualmente

gcc -Iparent/path/of/bar …

utilizar

gcc -isystem parent/path/of/bar …

en lugar. Desafortunadamente, este no es un control particularmente detallado. No conozco un mecanismo más específico.

Konrad Rudolph
fuente
4
en sonido metálico hay --system-header-prefix = opción, consulte clang.llvm.org/docs/...
dev_null
49

Una mejor solución de GCC: use #pragma.

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-W<evil-option>"
#include <evil_file>
#pragma GCC diagnostic pop

por ejemplo:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <QtXmlPatterns>
#pragma GCC diagnostic pop
Puntilla
fuente
Esto no es lo que quiero. Busco una manera de deshabilitar las advertencias para todos los archivos que comienzan con "Qt" (para seguir con su ejemplo. No solo para un solo archivo con nombre. Ya usamos diagnóstico push / pop, pero desafortunadamente esto no puede hacer una coincidencia de comodines en los nombres de archivo por lo que hemos visto.
Johannes Schaub - litb
Lo siento, he entendido mal. AFAIK, solo tiene dos opciones: crear un archivo de encabezado que incluya todos los encabezados en cuestión, envuelto en el diagnóstico de #pragma e inclúyalo primero (y cuente con guardias de inclusión múltiple para procesar los archivos solo una vez). O bien, trate los encabezados como encabezados del sistema con -isystem. No creo que haya una manera de definir reglas de diagnóstico personalizadas basadas en la ruta de inclusión (más allá del comportamiento de isystem). Siempre he usado el enfoque "crear un" archivo "include_all_bar.h" para este problema.
Brad
13
Tengo que decir que si bien esta respuesta no es la más votada, creo que es muy útil. Aunque no cumple con la pregunta original (todas las bibliotecas en una ruta / prefijo), proporciona una forma de excluir selectivamente algunas advertencias para un conjunto dado de encabezados. 👍
benschumacher
36

Cuando uso g++y tengo encabezados de terceros que generan toneladas de advertencias con mis valores predeterminados habituales de -Wall -Wextra& co. Tiendo a agruparlos en inclusiones separadas, especificando el .system_header #pragma

[...] GCC da un tratamiento especial al código que se encuentra en los encabezados del sistema. Todas las advertencias, excepto las generadas por #warning(consulte Diagnósticos), se suprimen mientras GCC procesa un encabezado del sistema. Las macros definidas en un encabezado del sistema son inmunes a algunas advertencias dondequiera que se expandan. Esta inmunidad se concede de forma ad-hoc, cuando encontramos que una advertencia genera muchos falsos positivos debido al código en las macros definidas en los encabezados del sistema.

[...]

También hay una directiva, #pragma GCC system_headerque le dice a GCC que considere el resto del archivo de inclusión actual como un encabezado del sistema, sin importar dónde se encuentre. El código que viene antes del #pragmaen el archivo no se verá afectado. #pragma GCC system_headerno tiene ningún efecto en el archivo de origen principal.

Prefiero esta solución a la anterior -isystemporque es más detallada y puedo ponerla directamente en las fuentes, sin jugar demasiado con los argumentos de la línea de comandos y los directorios de inclusión.

Ejemplo con la horrible biblioteca raíz:

#ifndef ROOTHEADERS_HPP_INCLUDED
#define ROOTHEADERS_HPP_INCLUDED
#ifdef __GNUC__
// Avoid tons of warnings with root code
#pragma GCC system_header
#endif
#include "TH1F.h"
#include "TApplication.h"
#include "TGraph.h"
#include "TGraph2D.h"
#include "TCanvas.h"
#endif
Matteo Italia
fuente
2
Oh, muy bien. +1 ... desafortunadamente, estos archivos tienden a aparecer antes que otros archivos de inclusión y la aplicación del pragma parece afectar al resto del archivo, es decir, todos los archivos de inclusión siguientes.
Konrad Rudolph
@Konrad Rudolph: ¿Estás seguro de eso? ¿no es solo para una inclusión y sus subincluidos?
Amir Zadeh
1
@Green Sí, eso es lo que quise decir. Aún así, esto requiere que coloque todas las inclusiones cuestionables al final de la lista de inclusión (y como he dicho, eso a menudo no es deseable o incluso posible) o coloque todas las inclusiones cuestionables en un encabezado separado, que luego incluirá. Esta tampoco es una opción perfecta en un gran proyecto colaborativo.
Konrad Rudolph
2
@Konrad: la segunda solución es la que adopté.
Matteo Italia
0

Supongo que la solución más simple sería escribir un script simple que llame al compilador, compile y elimine la salida no deseada, según el nombre del archivo y el tipo de advertencia. Puede utilizar diferentes scripts para cada compilador.

Simplemente actualice su archivo MAKE para usar este script en lugar de llamar directamente al compilador.

Gilad Naor
fuente