Perché dovremmo voler disabilitare gli avvisi del compilatore?


26

Questa risposta e i commenti aggiunti mostrano un modo per disabilitare diversi avvisi del compilatore usando le #pragmadirettive.

Perché uno vorrebbe farlo? Di solito gli avvisi sono lì per un motivo e ho sempre pensato che fossero buoni motivi. Esiste un "caso valido" in cui gli avvisi devono essere disabilitati? In questo momento non riesco a pensare a nessuno, ma forse sono solo io.


4
Non sono sicuro del motivo per cui qualcuno ha contrassegnato questo per chiudere. Mi sembra una domanda eminentemente ragionevole. +1

@Alastair Pitts: ho proposto una migrazione ai programmatori. Ho capito il mio errore più tardi.
Tugrul Ates,

3
I messaggi di avviso sono lì per un motivo, sì, ma c'è anche un motivo per cui non sono messaggi di errore .
Solomon Slow,

2
@jameslarge Il tuo commento riassume bene la situazione. Un avvertimento è il compilatore che ti dice che una situazione è plausibilmente sbagliata , il che implica probabilmente giusto . Se fosse sicuramente sbagliato , sarebbe un errore. Poiché alcuni avvisi possono essere falsi positivi, dovrebbe esserci sempre un modo per scrivere codice in modo tale da eliminare l'avviso. Sfortunatamente, a volte il modo più pragmatico per farlo è attraverso un pragma; da qui il nome.
Eric Lippert,

Non è disabilitante, si nasconde. Il problema sarà ancora lì solo che non lo vedrai così com'è
Sisir

Risposte:


11

Ho sempre avuto una situazione in cui ho disabilitato un avviso. Considero errori di avviso, quindi normalmente non rilascerei con avvisi. Tuttavia, durante lo sviluppo di un'API presso un cliente, ho affrontato il problema che un metodo che era necessario in una fase di migrazione da un'applicazione e che nessun altro avrebbe mai dovuto usare doveva essere incluso nella libreria.

Il modo migliore che ho trovato per dire a tutti gli utenti dell'API che non avrebbero dovuto chiamare questo metodo era di contrassegnarlo come obsoleto. Ciò, tuttavia, significava che l'unico caso d'uso valido era contrassegnato come un avviso di compilazione.

Eric Lippert ha scritto alcuni post sugli avvisi in cui troverai informazioni su come il team del compilatore pensa agli avvisi.

Campi interni di tipi interni

Le direttive non utilizzate non sono contrassegnate da avvisi


10

Ecco alcuni avvisi in cui la documentazione fornisce i motivi per cui potresti voler disabilitarli:

Altri esempi includono avvertenze sull'uso di metodi deprecati se sai che vuoi ancora usare il vecchio metodo o avere membri privati ​​che non vengono mai letti localmente, ma con la riflessione.

Nella mia esperienza, C # ha meno bisogno di disabilitare gli avvisi rispetto ad altre lingue come C ++. Ciò è in gran parte dovuto al fatto che, come afferma Eric Lippert nel suo blog , "cercano di riservare avvisi solo per quelle situazioni in cui possiamo dire con quasi certezza che il codice è rotto, fuorviante o inutile".


3
Bello. Penso che il primo sia il più chiaro, perché fornisce un caso molto specifico e una giustificazione (il terzo, ad esempio, mostra un pezzetto di codice che non passerebbe mai in rassegna il mio team). Questa domanda parla di avvisi obsoleti / deprivati. Fondamentalmente, sono ancora necessari nel codice legacy, ma si desidera scoraggiare qualsiasi nuovo codice dall'utilizzarli. Il codice legacy dovrebbe avere gli avvisi soppressi.
Greg Jackson,

Ho fatto molta programmazione macro in Excel e ho dovuto disabilitare gli avvisi per vari motivi come il salvataggio automatico, l'uscita automatica, le notifiche, ecc. Naturalmente potresti non essere attivo su questi avvisi ...
Dave Mess

@ICR Non ricordo affatto di aver disabilitato gli avvisi del compilatore in Java. Tutto quello che faccio è evitare l'uso di metodi obsoleti.
Mahmoud Hossam,

@Mahmoud Mi ritrovo molto spesso a dover sopprimere gli avvisi "non controllati" quando faccio qualcosa di persino complesso in remoto con i generici. Ma probabilmente non è giusto raggruppare Java con C ++ sul ridicolo avvertimento - ho modificato la mia risposta.
ICR,

@ICR Java impone l'uso dei generici per fornire la sicurezza dei tipi nelle raccolte, mentre alcuni lo vedono come un vincolo, lo considero una caratteristica, rende la scrittura del codice un po 'dolorosa, ma salva vite, e sì, output del compilatore C ++ è un po 'spaventoso quando si tratta di STL o altro con i modelli.
Mahmoud Hossam,

8

Un esempio in C che incontro varianti di regolarmente:

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

L'argomento è pertinente solo su alcune piattaforme, ma su quelle in cui non è pertinente il mio compilatore si lamenterà, e poiché gli avvisi sono convertiti in errori, ne impedirà la creazione.

La conversione di avvisi in errori richiede praticamente un tratteggio di escape per "non questo, lo so meglio del compilatore in questo caso".


6

Molte librerie Java indispensabili non sono mai state aggiornate per eliminare la necessità di tipografie non sicure. La soppressione di tali avvisi è necessaria in modo che altri avvisi più importanti vengano rilevati e corretti.


5

Faccio un lavoro integrato e mi sembra di ricordare un paio di volte quando ho disabilitato gli avvisi perché stavo facendo qualcosa che sembrava inutile per il compilatore, ma che in realtà aveva effetti reali sull'hardware.

L'unica altra volta è quando sto lavorando su codebase con idee disparate su alcune strutture di dati (come come rappresentare array di byte - char o unsigned char?). In questi casi potrei disabilitare gli avvisi perché l'alternativa è passare giorni a leggere il codice e modificare una porzione o inserire centinaia di cast.


3

Esistono diversi motivi per disabilitare in modo selettivo gli avvisi del compilatore, anche per i progetti che perseguono le migliori pratiche.

  • Compilatori diversi (o versioni diverse degli stessi compilatori) : i
    compilatori gestiscono gli avvisi in modo finemente diverso. Fornire avvisi di falsi positivi che non incidono su altri compilatori. In questo caso potrebbe avere senso disabilitare l'avviso per quei compilatori, invece di modificare il codice valido per silenziare un avviso falso positivo che ha effetto solo su alcuni compilatori, specialmente per i compilatori più vecchi che alla fine non saranno più supportati.
  • Con il codice generato:
    alcuni avvisi relativi all'igiene del codice (codice morto, duplice corpo di istruzioni condizionali, confronti che superano i limiti di tipo) possono essere tranquillamente ignorati poiché sono innocui e il compilatore li ottimizzerà.
    La generazione di codice che non genera questi avvisi innocui è ovviamente anche un'opzione, ma potrebbe essere più un problema che un valore.
  • Avvertenze per codice esterno:
    forse usi un'implementazione di checksum qsort o md5 ben nota inclusa nel tuo progetto. Il codice viene utilizzato da molti progetti e noto per funzionare bene, ma potrebbero esserci alcuni avvisi difficili che normalmente si correggono per il proprio codice.
    Per il codice esterno, tuttavia, potrebbe essere meno fastidi semplicemente disabilitare l'avviso (supponendo che sia sicuramente innocuo).
  • Avvisi causati dalle intestazioni di sistema:
    anche se GCC / Clang, ad esempio -isystem, supportano , ci sono casi in cui le differenze nelle intestazioni di sistema causano avvisi che possono essere ignorati (forse una funzione ha un valore di ritorno con segno su un sistema ma non su un altro), attivando -Wsign-compareavvisi.
    Un altro caso potrebbe essere la definizione di macro nelle intestazioni di sistema, è possibile copiare e incollare le macro nel proprio codice per modificarle, ma tutto considerato è meglio non doversi preoccupare di mantenere le macro da librerie di terze parti ... quindi è meglio solo per zittire l'avvertimento (forse la macro manca un cast causando -Wsign-conversionad esempio).
  • Avvisi inutilizzati nel codice stub:
    è possibile avvisare dei parametri non utilizzati, tuttavia quando si esegue lo stub di un'intera libreria in un singolo file che contiene solo funzioni stub - non è utile forzare (void)arg1; (void)arg2; (void)arg3; ...nel corpo di ogni funzione stub.
    Meglio solo sopprimere -Wunused-parameterin questo caso.

Si noti che in tutti questi esempi, la sua assunte disabilitando gli avvertimenti non è andando a nascondere insetti reali, ad esempio: -Wredundant-decls, -Wunused-parameter, -Wdouble-promotion, forse -Wpedantic... e che sai quello che stai facendo!


2

Valido o meno, a volte viene eseguito per ignorare la direttiva "tratta avvisi come errori" sul server di compilazione.

A parte questo, non riesco a pensare a nessuno dei due. Gli avvisi per disabili sono di solito un segno di un "brutto hax" ...


2

L'ultima volta che abbiamo disabilitato alcuni avvisi, è stato perché uno stagista ci aveva lasciato con un codice errato. Ho funzionato molto meglio, con chiari confini di conversione che sostituiscono la rappresentazione casuale dei dati.

Nel frattempo, dovevamo compilarlo e volevamo che l'opzione "Gli avvisi sono errori", quindi abbiamo eliminato alcuni degli avvisi.


2

Attualmente, l'unico avvertimento che abbia mai ignorato è

  warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

Perché microsoft non implementa le specifiche C ++ (la documentazione dice anche che non lo fanno!) E consente alle funzioni di dichiarare lanci specifici e tutte le funzioni possono solo lanciare (()) o lanciare (...), cioè niente o tutto.

Da HelpViewer 1.1:

 A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
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.