2016-07-12 35 views
12

Il test test riproducibile ridotto per VS2015 update 2 è il seguente. Stavamo tentando di costruire con "Warning Level 4" e trattiamo gli avvertimenti come errori fatali per migliorare le possibilità di notare gli avvertimenti. Spero che qualcuno nella comunità si sia già imbattuto in questo e abbia trovato una soluzione ragionevole.Come evitare un avviso di codice irraggiungibile a causa di un errore del compilatore?

Questo potrebbe rivelarsi troppo localizzato se nessun altro ha visto un problema equivalente, quindi mi piacerebbe notare che la domanda di fondo è "quanto male si dovrebbe manipolare il codebase per eludere i poveri avvisi del compilatore", o in modo equivalente, "come si dovrebbe segnalare bug a un venditore di compilatori che perde segnalazioni di errori".

#ifdef _WIN32 
#pragma warning(push) 
#pragma warning(disable : 4702) // As suggested by comments 
#endif 
template <class Type> 
void func (Type t) 
{ 
    t.func(); 
    t.func(); 
} 
#ifdef _WIN32 
#pragma warning(pop) 
#endif 

struct NoThrow 
{ 
    void func() {} 
}; 

struct Throws 
{ 
    void func() {throw 1;} 
}; 

int main() 
{ 
    NoThrow nt; 
    func (nt); 

    Throws t; 
    func (t); 
} 

Ciò attiva avvisi di codice irraggiungibili. La funzione basata su modelli sembra ragionevole da sola, ma per una particolare istanziazione il compilatore è in grado di determinare che il secondo t.func() è morto, quindi avvisa del codice irraggiungibile.

Questa sembra una qualità di taglio abbastanza chiara del problema di implementazione per VS2015, quindi abbiamo aperto un bug report here.

Abbiamo ricevuto alcune indicazioni da Microsoft,

Purtroppo il backend del compilatore (dove ha origine questo avviso) non ha vero concetto di istanze funzione template come esempi di una singola funzione template. Sono tutte funzioni solo con nomi dall'aspetto molto simile, se mai si è preso la briga di confrontare i nomi (decorati) tra loro. Che non fa mai Quindi, ciò che vede qui è una funzione con un codice irraggiungibile, che avvisa, e un'altra funzione senza codice irraggiungibile, che non è così. Questo concetto di "avvertenza cross-function" che proponete, dove raccogliamo e confrontiamo i dati tra diverse istanze di modelli e avvertiamo solo se questo o quello, è estremamente difficile sotto un puro binario LTCG e altrimenti impossibile.

Considera un modello Foo in un'intestazione foo.h. Supponiamo che a.cpp lo includa e crei Foo, con un codice irraggiungibile, e quindi b.cpp lo includa e crei Foo senza codice irraggiungibile. Proponi che in a.cpp Foo non debba avvisare, nonostante il codice irraggiungibile, perché Foo esiste senza codice irraggiungibile. Ma, Foo è compilato in un file diverso, in un processo diverso, in una diversa chiamata di cl.exe e in modo non appropriato in futuro. Chiaramente il compilatore non ha la possibilità di raggiungere nel futuro un processo non ancora nato e di ottenere le informazioni necessarie per calcolare se dovrebbe avvisare o meno.

L'unica opzione valida che abbiamo qui è disattivare l'avviso di codice irraggiungibile per i modelli tutti insieme, che sarò onesto, non accadrà fino a quando non siamo sicuri che il danno arrecato è maggiore del buono fatto (è un netto cattivo). Gli avvertimenti hanno falsi positivi, succede. Proverò a pensare ad altre opzioni e a esaminare il numero di riga/la cosa del file.

Il link qui sopra potrebbe non essere disponibile, ma come internet è dotato di cache si può vedere una copia here o trovare il proprio utilizzando 2.744.730 e scorretta-irraggiungibile-codice-warning-in-modello-esemplificazione.

Quindi, se si presuppone che il modello di istanziazione del modello sottostante stia stampando copie di funzioni e quindi li sottoponga alla stessa analisi di avvisi di qualsiasi altro, come possiamo evitare gli avvisi di codice guasto? Al momento sono combattuto tra l'aggiunta di tag di invio alla dozzina circa di modelli che sono attualmente interessati o che disattivano gli avvisi a livello globale.

edit: Il collegamento diretto sembra essere rivivere

+3

['#pragma warning'] (https://msdn.microsoft.com/en-us/library/2c8f766e.aspx) potrebbe essere unidirezionale. –

+2

Seguirò il suggerimento di Igor con l'aggiunta che dovrebbe esserci un commento che identifica la versione del compilatore e, se possibile, il collegamento al bug report per dare al programmatore di manutenzione e l'idea di PERCHÉ l'avviso è disabilitato. (e se possibile, riattivare l'avviso alla fine dell'espansione del modello - (questo potrebbe non funzionare con le espansioni dei modelli, però.)) –

+3

Onestamente, la dichiarazione di Microsoft ha senso per me. Ti stanno aggressivamente fornendo avvisi per aiutarti. I modelli sono un'area in cui non possono fornire avvisi accurati di istanziazione. Se ti infastidisce, puoi 'pragma' questi avvertimenti. Ma in questo caso vorrei prendere e ri-lanciare, il che non solo cancellerebbe gli avvertimenti per te, ma chiarirebbe cosa sta succedendo nel tuo codice. –

risposta

1

direi che questo è il comportamento corretto, fastidioso come può essere. L'implementatore di

template <class Type> 
void func (Type t) 
{ 
    t.func(); 
    t.func(); 
} 

potrebbe essere abbastanza contento di questo avviso. Inoltre, non è spesso possibile che il compilatore decida se non ci sarebbero nessuno, alcuni, tutti Type che genererebbero codice non valido o valido. Pertanto, attende che sia specificato Type e continui principalmente come se il codice fosse stato inserito con quel tipo fisso.

Problemi correlati