Disabilita errore di avviso singolo


115

C'è un modo per disabilitare solo una singola riga di avviso in un file cpp con Visual Studio?

Ad esempio, se rilevo un'eccezione e non la gestisco, ottengo l'errore 4101 (variabile locale non referenziata). C'è un modo per ignorarlo solo in quella funzione, ma altrimenti segnalarlo nell'unità di compilazione? Al momento, lo metto #pragma warning (disable : 4101)in cima al file, ma questo ovviamente lo spegne solo per l'intera unità.


19
se si menziona solo il tipo e non si nomina l'eccezione, non ci sarà alcun avviso. Ad esempio catch (const std::exception& /* unnamed */) {.... }. Non risponde alla tua domanda, ma potrebbe risolvere il tuo problema.
Sjoerd

Risposte:


182
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 

1
@ Cookie: sì, funziona per qualsiasi parte di codice che passa attraverso il compilatore.
Matteo Italia

Per una risposta più recente e concisa, vedere la risposta di Daniel Seither, di seguito.
Dan Nissenbaum

4
clangnon sembrano sostenere questo pragma, ma si può ottenere lo stesso effetto con #pragma clang diagnostic push, #pragma clang diagnostic ignored "-Wunused-variable"e #pragma clang diagnostic pop. Vedere "Controllo della diagnosi tramite Pragmas" nel Manuale dell'utente di Clang
rampion

Dato che uso questa funzione raramente, quando lo faccio, di solito finisco su questa pagina per ricordare a me stesso la sintassi. Ho appena messo in giro una chiamata a una funzione deprecata che potrebbe non essere mai aggiornata, in modo che l'avviso non mi infastidisca negli elenchi del compilatore, che analizzo religiosamente.
David A. Gray

Per Visual Studio, l'argomento della riga di comando è /wd4101. Nota che non c'è la normale :tra la bandiera e il numero e non puoi creare un elenco di numeri separati da virgole. Per altri compilatori potrebbe essere /nowarn:4101invece.
Jesse Chisholm

89

Se desideri sopprimere un avviso in una singola riga di codice, puoi utilizzare l' suppress identificatore di avviso :

#pragma warning(suppress: 4101)
// here goes your single line of code where the warning occurs

Per una singola riga di codice, funziona come scrivere quanto segue:

#pragma warning(push)
#pragma warning(disable: 4101)
// here goes your code where the warning occurs
#pragma warning(pop)

8
Molto utile! Sfortunatamente, non funziona per una singola riga che include un'intestazione che genera l'avviso.
Marko Popovic

2
@MarkoPopovic: La suppressspecificatore opera su un unico, pre-elaborato riga di codice. Se la riga che segue #pragma warning(suppress: ...)è una #includedirettiva (che espande il file a cui fa riferimento il suo parametro nell'unità di compilazione corrente), l'effetto si applica solo alla prima riga di quel file. Questo dovrebbe essere ovvio, poiché gli avvisi vengono generati dal compilatore. Il compilatore opera su codice preelaborato.
Rilevabile

@IInspectable In tal caso la chiamerei una riga di codice post-elaborata . pre-elaborato significa che non è stato ancora tradotto dal preprocessore.
void.pointer

2
@voi: il finale "-ed" indica il participio passato . È usato per esprimere che qualcosa è finito nel passato. Una linea "pre-elaborata" è una linea che è stata completamente elaborata.
Rilevabile il

29

#pragma push / pop sono spesso una soluzione per questo tipo di problemi, ma in questo caso perché non rimuovi semplicemente la variabile non referenziata?

try
{
    // ...
}
catch(const your_exception_type &) // type specified but no variable declared
{
    // ...
}

6
Questa non è una risposta alla domanda. Certo, questo potrebbe risolvere il problema di OP, ma non aiuterà i futuri lettori con una domanda simile: "come faccio a disattivare un avviso specifico per una parte specifica del mio codice?"
Sjoerd

1
@Sjoerd: tre persone hanno già risposto alla "domanda ufficiale" che altre persone potrebbero cercare, quindi invece ho provato a leggere tra le righe e risolvere il suo vero problema (arrivando un minuto dopo il tuo commento :P).
Matteo Italia

11
@Sjoerd come futuro lettore attesto che questa risposta in effetti mi ha aiutato.
Lunedì

2
@ Mołot: come scrittore del passato, sono contento che abbia aiutato. =)
Matteo Italia

9

Usa #pragma warning ( push ), quindi #pragma warning ( disable ), quindi inserisci il tuo codice, quindi usa #pragma warning ( pop )come descritto qui :

#pragma warning( push )
#pragma warning( disable : WarningCode)
// code with warning
#pragma warning( pop ) 

8

Esempio:

#pragma warning(suppress:0000)  // (suppress one error in the next line)

Questo pragma è valido per C ++ a partire da Visual Studio 2005.
https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

Il pragma NON è valido per C # tramite Visual Studio 2005 tramite Visual Studio 2015.
Errore: "Disattivazione o ripristino previsti".
(Immagino che non siano mai riusciti a implementare suppress...)
https://msdn.microsoft.com/en-us/library/441722ys(v=vs.140).aspx

C # richiede un formato diverso. Sarebbe simile a questo (ma non funzionerebbe):

#pragma warning suppress 0642  // (suppress one error in the next line)

Invece di suppress, devi disablee enable:

if (condition)
#pragma warning disable 0642
    ;  // Empty statement HERE provokes Warning: "Possible mistaken empty statement" (CS0642)
#pragma warning restore 0642
else

È COSÌ brutto, penso che sia più intelligente ridisegnarlo:

if (condition)
{
    // Do nothing (because blah blah blah).
}
else

5

Invece di mettere in cima al file (o anche un file di intestazione), basta inserire il codice in questione con #pragma warning (push), #pragma warning (disable)e un abbinamento #pragma warning (pop), come mostrato qui .

Sebbene ci siano altre opzioni, tra cui #pramga warning (once).


5

Si può anche usare UNREFERENCED_PARAMETERdefinito in WinNT.H. La definizione è solo:

#define UNREFERENCED_PARAMETER(P)          (P)

E usalo come:

void OnMessage(WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(wParam);
    UNREFERENCED_PARAMETER(lParam);
}

Perché dovresti usarlo, potresti obiettare che puoi semplicemente omettere il nome della variabile stessa. Bene, ci sono casi (configurazione di progetto diversa, build di debug / rilascio) in cui la variabile potrebbe essere effettivamente utilizzata. In un'altra configurazione quella variabile è inutilizzata (e quindi l'avvertimento).

Alcune analisi statiche del codice possono ancora fornire un avviso per questa dichiarazione priva di senso ( wParam;). In tal caso, è possibile utilizzare la DBG_UNREFERENCED_PARAMETERstessa procedura delle UNREFERENCED_PARAMETERbuild di debug e P=Pdella build di rilascio.

#define DBG_UNREFERENCED_PARAMETER(P)      (P) = (P)

1
nota che da C ++ 11 abbiamo l' [[maybe_unused]]attributo
metablaster

2

Se vuoi disabilitare unreferenced local variablescrivi in ​​qualche header

template<class T>
void ignore (const T & ) {}

e utilizzare

catch(const Except & excpt) {
    ignore(excpt); // No warning
    // ...  
} 

2
Una chiamata di funzione, solo per sopprimere l'avviso? Perché non lo fai invece (void)unusedVar;:?
Nawaz

@Nawaz: Penso che (void)unusedVar;?non sia conforme allo standard C ++.
Alexey Malistov

2
È un'espressione il cui valore è niente. In C ++ puoi persino fare static_cast<void>(unusedVar).
Nawaz


2
§5.2.9 / 4 dice, Any expression can be explicitly converted to type “cv void.” The expression value is discardedsecondo il quale puoi scrivere static_cast<void>(unusedVar)e static_cast<const void>(unusedVar)e static_cast<volatile void>(unusedVar). Tutti i moduli sono validi. Spero che chiarisca il tuo dubbio.
Nawaz

2

In certe situazioni devi avere un parametro denominato ma non lo usi direttamente.
Ad esempio, mi sono imbattuto in VS2010, quando 'e' è usato solo all'interno di decltypeun'istruzione, il compilatore si lamenta ma devi avere la variabile nominata e.

Tutti i suddetti non #pragmasuggerimenti si riducono alla semplice aggiunta di una singola affermazione:

bool f(int e)
{ 
   // code not using e
   return true;
   e; // use without doing anything
}

1
ora (nel compilatore MS VS2015) questo causa il codice C4702 non raggiungibile
Cee McSharpface

2

come menzionato da @rampion, se sei in clang gcc, gli avvisi sono per nome, non per numero, e dovrai fare:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
// ..your code..
#pragma clang diagnostic pop

questa informazione proviene da qui

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.