Disattivare selettivamente gli avvisi GCC solo per una parte di un'unità di traduzione?


85

Qual è l'equivalente GCC più vicino a questo codice preprocessore MSVC?

#pragma warning( push )                    // Save the current warning state.
#pragma warning( disable : 4723 )          // C4723: potential divide by 0
// Code which would generate warning 4723.
#pragma warning( pop )                     // Restore warnings to previous state.

Abbiamo codice nelle intestazioni comunemente incluse che non vogliamo generare un avviso specifico. Tuttavia, vogliamo che i file che includono quelle intestazioni continuino a generare quell'avviso (se il progetto ha quell'avviso abilitato).


Se le intestazioni sono installate in / usr / include o cosa hai, gcc non genera avvisi per loro di default.
Spudd86

Risposte:


95

Questo è possibile in GCC dalla versione 4.6, o intorno a giugno 2010 nel bagagliaio.

Ecco un esempio:

#pragma GCC diagnostic push
#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 */

8
La funzionalità push e pop è stata aggiunta in gcc 4.6 ( gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html ).
Dave Johansen

1
Probabilmente vorrai spingere due volte se stai per scoppiare due volte.
Dan

2
@ Dan: leggi il manuale e commenta. Nota l'origine dell'esempio.
Matt Joiner

Cordiali saluti per le versioni precedenti come 4.4.7 è ancora possibile utilizzare il #pragma GCC diagnostic [error|warning|ignored]ma popnon è implementato / supportato.
Trevor Boyd Smith

36

La cosa più vicina è il file pragma diagnostica GCC , #pragma GCC diagnostic [warning|error|ignored] "-Wwhatever". Non è molto vicino a ciò che desideri e vedi il link per dettagli e avvertenze.


1
Sapete quale e dove potrebbe essere la motivazione per non aggiungere questa funzionalità? (Non sono riuscito a trovarlo.) Trovo utile l'avviso push-disable-pop.

1
Non immagino davvero che "non aggiungere funzionalità" a gcc tenda ad avere una logica tanto quanto l'assenza di qualcuno che invii una patch funzionante.
caos

14
Non è che nessuno sia disposto a fare il lavoro per questo tipo di controllo degli avvisi a grana fine in gcc, o inviare il codice: conosco una delle principali società della Silicon Valley che lo ha già fatto, e un'altra che sarebbe stata felice di pagare qualcuno per farlo e inserire il codice nello stream. Piuttosto, per una discussione con un ragazzo che (come uno dei manutentori di gdb) è collegato a questa roba, i manutentori di gcc hanno una filosofia: "Se c'è un avviso, è un bug e devi risolverlo". Quindi (imo) è un argomento religioso e controllano il codice in modo da vincere.
Bob Murphy

Per aggiungere al commento di Bob, gli sviluppatori di GCC hanno una storia di non gradimento della #pragmadirettiva, quindi tutto ciò che è specifico di GCC è probabilmente più probabile che venga implementato come file __attribute__((foo)).
Tom

10
il nuovo gcc (> = 4.4) ha #pragma GCC push_optionscosì puoi masticare con più della semplice diagnostica ... gcc.gnu.org/onlinedocs/gcc/…
Spudd86

33

Ho fatto qualcosa di simile. Per il codice di terze parti, non volevo vedere alcun avviso. Quindi, piuttosto che specificare -I/path/to/libfoo/include, ho usato-isystem /path/to/libfoo/include . Questo fa sì che il compilatore tratti quei file di intestazione come "intestazioni di sistema" ai fini degli avvisi, e finché non li abiliti -Wsystem-headers, sei per lo più al sicuro. Ho ancora visto alcuni avvertimenti fuoriuscire da lì, ma riduce la maggior parte della spazzatura.

Nota che questo ti aiuta solo se puoi isolare il codice offensivo tramite include-directory. Se è solo un sottoinsieme del tuo progetto o mescolato con altro codice, sei sfortunato.


1
Ottimo suggerimento. Se si utilizza LLVM, aggiungere il flag -isystem in "Altri flag C" nella sezione "Compilatore LLVM Apple - Lingua".
Nestor

@ Tom, grazie per la condivisione. Non riesco a capire dove utilizzare la tua soluzione. Puoi dire ancora un po '?
Lorenzo B

1

Questa è un'espansione della risposta di Matt Joiner .

Se non vuoi generare pragmi in tutto il codice, puoi usare l' operatore _Pragma :

#ifdef __GNUC__
#  define DIAGNOSTIC_ERROR(w) _Pragma("GCC diagnostic error \"" w "\"")
#  define DIAGNOSTIC_IGNORE(w) _Pragma("GCC diagnostic ignore \"" w "\"")
#  define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
#  define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#endif
// (...)

DIAGNOSTIC_ERROR("-Wuninitialized")
foo(a); // Error

DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE("-Wuninitialized")
foo(a); // No error

DIAGNOSTIC_POP
foo(a); // Error
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.