Come gestire gli avvertimenti in un progetto legacy

8

Lavoro su un progetto C ++ che genera bajillions di avvertimenti. La maggior parte degli avvertimenti è apparso dopo che il codice è stato scritto:

  • Inizialmente il progetto utilizzava Visual C ++ 8, passando presto a 9, ma c'è poca differenza negli avvisi generati. Gli avvertimenti erano fissi o ridotti al silenzio, quindi non c'erano avvertimenti allora.
  • Quindi è stata aggiunta una destinazione a 64 bit. Ha generato un'enorme quantità di avvisi, principalmente a causa dell'uso non corretto dei tipi (ad esempio unsigned rispetto a size_t ). Nessuno si è preoccupato, o ha avuto il tempo, di risolverli una volta che il codice ha funzionato per lo scopo.
  • Successivamente è stato aggiunto il supporto per altre piattaforme che utilizzano GCC (4.5 e 4.6, alcune 4.4 inizialmente). GCC è molto più schizzinoso, quindi ha generato molti più avvisi. Di nuovo nessuno si è preoccupato, o ha avuto tempo, di sistemarli. Ciò è stato complicato dal fatto che GCC non aveva un pragma per mettere a tacere un avvertimento in particolare bit di codice fino alla 4.5, e secondo la documentazione non è ancora quello di cui si avrebbe bisogno.
  • Nel frattempo sono comparsi alcuni avvisi obsoleti.

Quindi ora abbiamo un progetto che genera migliaia di avvisi. E non posso nemmeno dire da quanti posti, dato che anche i file .cpp sono compilati più volte da diversi compilatori e gli avvisi nelle intestazioni vengono stampati più e più volte.

C'è una buona pratica per ripulire qualcosa del genere? O almeno qualche esperienza positiva che ha a che fare con esso?

    
posta Jan Hudec 02.04.2013 - 08:55
fonte

5 risposte

4

Non toccare alcun codice legacy. Trova un modo per sopprimere gli avvertimenti per ora. Apportare modifiche apparentemente innocue al codice può introdurre bug nel codice che, presumo, è già stato testato ed è relativamente privo di bug.

Sopprimendo tutti gli avvertimenti che sono attualmente nella base di codice, puoi fingere di avere una lavagna pulita. Eventuali nuovi avvertimenti introdotti nel codice dovrebbero essere eliminati e, quando il vecchio codice viene riscritto, la nuova implementazione non dovrebbe sopprimere gli avvertimenti.

I tuoi obiettivi qui dovrebbero essere:

  1. Riduci il rapporto segnale / rumore. Se gli sviluppatori vedono migliaia di notifiche quando costruiscono, non noteranno che il ramo principale ha notifiche del 2004 e la loro filiale ha il 2006.

  2. Non introdurre più bug. Facendo le sopraccennate modifiche innocue, potresti introdurre dei bug non appropriati. Ciò è particolarmente pertinente quando si hanno migliaia di avvisi. Anche se il tuo tasso di errore è incredibilmente basso, hai ancora migliaia di possibilità di rovinare.

  3. Non lasciare che il codice precedente riduca gli standard per il nuovo codice. Solo perché gli avvertimenti per una classe sono stati soppressi non significa che la nuova classe possa fare lo stesso. Alla fine, con diligenza, il codice legacy sarà eliminato dalla base di codice e sostituito con un codice più nuovo e senza avvisi.

risposta data 02.04.2013 - 20:09
fonte
14

Penso che gli avvertimenti, che non sono trattati come errori, siano inutili. Ne ricevi tantissimi, quindi nessuno si preoccupa di guardarli, e non hanno il loro scopo.

Il mio suggerimento è di correggerli tutti e iniziare a trattarli come errori.
Fissarli sembra spaventoso, ma penso che si possa fare. Un buon programmatore che riprenderà questo lavoro molto presto individuerà il modo di affrontare ogni avvertimento e lo gestirà in modo molto meccanico e rapido.

Abbiamo fatto un progetto simile nella mia azienda, e ha funzionato - ora non abbiamo avvertenze nella parte del codice dove è importante per noi, e sto parlando di molte migliaia di file (non so come molti avvertimenti).

Questo deve essere immediatamente seguito trattando gli avvertimenti come errori. Una volta che una parte del tuo codice è priva di avvisi, modifica i flag di compilazione per questa parte e lascia che non vengano inseriti nuovi avvisi. Se non lo fai, troverai nuovi avvisi come funghi e il tuo lavoro verrà sprecato.

Una delle preoccupazioni che potresti avere è l'introduzione di bug come risultato della correzione degli avvertimenti. Ciò è particolarmente probabile perché il programmatore che fissa gli avvisi probabilmente non conosce la maggior parte del codice che sta cambiando. Tuttavia, la maggior parte delle modifiche sarebbe molto sicura, ad es. aggiungendo un prototipo di funzione o un cast.

    
risposta data 02.04.2013 - 11:14
fonte
3

Leggevo Norme di codifica C ++: 101 regole, linee guida e best practice e la seconda delle linee guida suggerisce "Compilare pulito a livelli di avviso elevati". Illustra una serie di motivi per cui non vorrai che molti avvertimenti in un programma e capo tra loro siano

  1. C'è un potenziale problema nel codice.
  2. Dovrebbe avere build silenziose e di successo e, in caso contrario, potrebbero mancare dei veri problemi.
  3. Gli avvertimenti benigni ignorati potrebbero oscurare gli avvisi che indicano i pericoli reali

I programmi che compaiono con gli avvertimenti possono sembrare corretti, ma è possibile che ci siano problemi reali con il codice che potrebbe crearsi in qualche punto. Vorrei suggerire di classificare gli avvertimenti, dare loro un livello di priorità e, quando hai tempo, correggerli.

    
risposta data 02.04.2013 - 17:04
fonte
1

O accantonare uno sprint / ciclo per fare manutenzione preventiva sul sistema, eliminare il dead code, eliminare gli avvertimenti, ripulire i commenti sbagliati, cose del genere, O istituire una politica per eliminare gli avvertimenti mentre le fonti vengono toccate comunque per qualcos'altro .
Non farei mai il primo solo per sbarazzarmi degli avvertimenti, ma se fosse stato pianificato un ciclo del genere sarebbe stato parte del carico di lavoro. Il motivo è che toccare un file per qualsiasi cosa introduce il rischio di bug e quindi rischia la stabilità del tuo prodotto.

    
risposta data 02.04.2013 - 09:03
fonte
1

Sento il tuo dolore perché mi trovo in una situazione simile. Il modo in cui ho affrontato il problema è: rimuovere gli avvisi di un modulo / sottoprogetto alla volta e impostare il flag di compilazione "trattare gli avvertimenti come errore" (Werr) per il modulo dopo che è stato ripulito. Inoltre, ho deciso di concentrarmi su una sola piattaforma, anche se abbiamo costruito diversi sistemi operativi con diversi compilatori. Infine, per le librerie di terze parti che compiliamo, spengo semplicemente gli avvisi.

Intendiamoci, sbarazzarsi di alcuni di questi avvertimenti è molto più facile a dirsi che a farsi. Ad esempio, size_t vs i problemi non firmati che hai menzionato possono causare overflow di interi se si limitano a silenziare gli avvertimenti con i cast, quindi in alcuni casi si sostituisce unsigned con size_t, in altri casi è necessario rilevare un overflow in fase di esecuzione. È tutto caso per caso - molto noioso e difficile.

    
risposta data 02.04.2013 - 17:39
fonte

Leggi altre domande sui tag