Domanda

Trovo spesso che la sezione delle intestazioni di un file diventi sempre più grande ma non diventa mai più piccola. Nel corso della vita di un file sorgente le classi potrebbero essere state spostate e modificate ed è molto probabile che ci siano parecchi #includes che non devono più essere presenti. Lasciandoli lì solo prolunga il tempo di compilazione e aggiunge dipendenze di compilazione non necessarie. Cercare di capire quali sono ancora necessari può essere piuttosto noioso.

Esiste un tipo di strumento in grado di rilevare le direttive #include superflue e suggerire quali posso rimuovere in sicurezza?
Forse non lo fanno i pelucchi?

È stato utile?

Soluzione

Non è automatico, ma doxygen produrrà diagrammi di dipendenza per #included File. Dovrai esaminarli visivamente, ma possono essere molto utili per ottenere un'immagine di ciò che sta usando cosa.

Altri suggerimenti

cppclean di Google (collegamenti a: download , documentazione ) può trovare diverse categorie di problemi C ++ e ora può trovare #includes superflui.

Esiste anche uno strumento basato su Clang, include-what- tu usi , questo può farlo. include-what-you-use può anche suggerire dichiarazioni in avanti (quindi non devi #includere così tanto) e facoltativamente ripulire i tuoi #include per te.

Le versioni attuali di Eclipse CDT hanno anche questa funzionalità integrata: andando nel menu Sorgente e facendo clic su Organizza Include includerà in ordine alfabetico le tue # include, aggiungerà eventuali intestazioni che Eclipse pensa di utilizzare senza includerle direttamente e commenterà eventuali intestazioni che non ritieni necessarie. Questa funzionalità non è affidabile al 100%, tuttavia.

Scopri anche include-what-you-use , che risolve un problema simile.

Il problema con il rilevamento di inclusioni superflue è che non può essere solo un controllo di dipendenza del tipo. Un'inclusione superflua è un file che non fornisce alcun valore alla compilazione e non modifica un altro elemento da cui dipendono altri file. Esistono molti modi in cui un file di intestazione può modificare una compilazione, ad esempio definendo una costante, ridefinendo e / o eliminando una macro utilizzata, aggiungendo uno spazio dei nomi che altera la ricerca di un nome in qualche modo lungo la riga. Per rilevare elementi come lo spazio dei nomi è necessario molto più di un preprocessore, in realtà è quasi necessario un compilatore completo.

Lint è più un controllo di stile e sicuramente non avrà questa piena capacità.

Penso che troverai l'unico modo per rilevare un'inclusione superflua è rimuovere, compilare ed eseguire le suite.

Ho pensato che PCLint avrebbe fatto questo, ma sono passati alcuni anni da L'ho visto. Potresti verificarlo.

Ho guardato questo blog e l'autore ha parlato un po 'della configurazione di PCLint per trovare inclusioni inutilizzate. Potrebbe valere la pena dare un'occhiata.

Il browser di refactoring CScout è in grado di rilevare direttive di inclusione superflue nel codice C (purtroppo non C ++). Puoi trovare una descrizione di come funziona in questo articolo di giornale.

Puoi scrivere uno script rapido che cancella una singola direttiva #include, compila i progetti e registra il nome in #include e il file da cui è stato rimosso nel caso in cui non si siano verificati errori di compilazione.

Lascialo funzionare durante la notte e il giorno successivo avrai un elenco corretto al 100% di file include che puoi rimuovere.

A volte la forza bruta funziona :-)


modifica: ea volte no :-). Ecco alcune informazioni dai commenti:

  1. A volte è possibile rimuovere due file di intestazione separatamente, ma non entrambi insieme. Una soluzione è rimuovere i file di intestazione durante l'esecuzione e non ripristinarli. Questo troverà un elenco di file che puoi rimuovere in sicurezza, anche se potrebbe esserci una soluzione con più file da rimuovere che questo algoritmo non troverà. (è una ricerca avida nello spazio dei file di inclusione da rimuovere. Troverà solo un massimo locale)
  2. Potrebbero esserci sottili cambiamenti nel comportamento se alcune macro sono state ridefinite in modo diverso a seconda di alcuni #ifdefs. Penso che si tratti di casi molto rari, e i Test di unità che fanno parte della build dovrebbero rilevare questi cambiamenti.

Siamo spiacenti di (ri) pubblicare qui, le persone spesso non espandono i commenti.

Controlla il mio commento a crashmstr, FlexeLint / PC-Lint farà questo per te. Messaggio informativo 766. La sezione 11.8.1 del mio manuale (versione 8.0) ne discute.

Inoltre, e questo è importante, continua a ripetere fino a quando il messaggio non scompare . In altre parole, dopo aver rimosso le intestazioni inutilizzate, rieseguire lint, è possibile che più file di intestazione siano diventati "non necessari". una volta rimosse alcune intestazioni non necessarie. (Potrebbe sembrare sciocco, leggilo lentamente e analizzalo, ha senso.)

Non ho mai trovato uno strumento completo che realizza ciò che stai chiedendo. La cosa più vicina che ho usato è IncludeManager , che rappresenta graficamente l'albero di inclusione dell'intestazione in modo da poter individua visivamente cose come le intestazioni incluse in un solo file e le inclusioni di intestazioni circolari.

Se stai utilizzando Eclipse CDT puoi provare http://includator.com che è gratuito per i beta tester (all'indirizzo il momento in cui scrivo) e rimuove automaticamente #inclusi superflui o aggiunge quelli mancanti. Per quegli utenti che hanno FlexeLint o PC-Lint e utilizzano Elicpse CDT, http://linticator.com potrebbe essere un'opzione (gratuito anche per il beta test). Mentre utilizza l'analisi di Lint, fornisce soluzioni rapide per rimuovere automaticamente le dichiarazioni #include superflue.

Ho provato a usare Flexelint (la versione unix di PC-Lint) e ho ottenuto risultati piuttosto contrastanti. Questo è probabilmente perché sto lavorando su una base di codice molto grande e intricata. Consiglio di esaminare attentamente ogni file segnalato come inutilizzato.

La preoccupazione principale sono i falsi positivi. Molteplici inclusioni della stessa intestazione vengono riportate come intestazione non necessaria. Ciò è negativo poiché Flexelint non ti dice su quale riga è inclusa l'intestazione o dove è stata inclusa in precedenza.

Uno dei modi in cui gli strumenti automatici possono sbagliare:

In A.hpp:

class A { 
  // ...
};

In B.hpp:

#include "A.hpp

class B {
    public:
        A foo;
};

In C.cpp:

#include "C.hpp"  

#include "B.hpp"  // <-- Unneeded, but lint reports it as needed
#include "A.hpp"  // <-- Needed, but lint reports it as unneeded

Se segui ciecamente i messaggi di Flexelint, confonderai le tue dipendenze #include. Ci sono più casi patologici, ma fondamentalmente dovrai ispezionare tu stesso le intestazioni per ottenere i migliori risultati.

Consiglio vivamente questo articolo su Struttura fisica e C ++ dal blog Games dall'interno. Raccomandano un approccio globale per ripulire il disordine #include:

  

Linee guida

     

Ecco una serie distillata di linee guida dal libro di Lakos che minimizzano il numero di dipendenze fisiche tra i file. Li uso da anni e sono sempre stato molto contento dei risultati.

     
      
  1. Ogni file cpp include prima il proprio file di intestazione. [Snip]
  2.   
  3. Un file di intestazione deve includere tutti i file di intestazione necessari per analizzarlo. [Snip]
  4.   
  5. Un file di intestazione deve avere il numero minimo di file di intestazione necessario per analizzarlo. [Snip]
  6.   

Questo articolo spiega una tecnica di rimozione di #include usando l'analisi di Doxygen. Questo è solo uno script perl, quindi è abbastanza facile da usare.

Esiste uno strumento gratuito Includi osservatore dipendenze file che può essere integrato nel studio visivo. Mostra i #inclusi superflui in rosso.

Forse un po 'in ritardo, ma una volta ho trovato uno script perl WebKit che ha fatto esattamente quello che volevi. Avrà bisogno di qualche adattamento credo (non sono esperto in perl), ma dovrebbe fare il trucco:

http : //trac.webkit.org/browser/branches/old/safari-3-2-branch/WebKitTools/Scripts/find-extra-includes

(questo è un vecchio ramo perché trunk non ha più il file)

Esistono due tipi di file #include superflui:

  1. Un file di intestazione effettivamente non necessario da il modulo (.c, .cpp)
  2. Il modulo richiede un file di intestazione ma essere incluso più di una volta, direttamente o indirettamente.

Esistono 2 modi nella mia esperienza che funzionano bene per rilevarlo:

  • gcc -H o cl.exe / showincludes (risoluzione del problema 2)

    Nel mondo reale, puoi esportare CFLAGS = -H prima di creare, se tutto il Makefile non ha la precedenza Opzioni CFLAGS. O come ho usato io può creare un wrapper cc / g ++ per aggiungere -H opzioni forzatamente per ogni invocazione di $ (CC) e $ (CXX). e anteporre il la directory di wrapper su $ PATH variabile, quindi il tuo make sarà tutto usa invece il comando wrapper. Di Naturalmente il tuo wrapper dovrebbe invocare il compilatore gcc reale. Questo inganna è necessario cambiare se il Makefile lo utilizza gcc direttamente. invece di $ (CC) o $ (CXX) o dalle regole implicite.

    Puoi anche compilare un singolo file modificando la riga di comando. Ma se vuoi pulire le intestazioni per l'intero progetto. Puoi catturare tutto l'output di:

    ripulisci

    crea 2 > & amp; 1 | tee result.txt

  • PC-Lint / FlexeLint (risolvi problema sia 1 che 2)

    assicurati di aggiungere le opzioni + e766, questo avviso riguarda: file di intestazione non utilizzati.

    pclint / flint -vf ...

    Ciò causerà l'output di pclint inclusi i file di intestazione, i file di intestazione nidificati verranno rientrati in modo appropriato.

Per terminare questa discussione: il preprocessore c ++ è in fase di completamento. È una proprietà semantica, se un'inclusione è superflua. Quindi, dal teorema di Rice risulta che è indecifrabile se una inclusione sia superflua o meno. NON PU be ESSERE un programma che rilevi (sempre correttamente) se un'inclusione è superflua.

Ecco un semplice il modo della forza bruta di identificare l'intestazione superflua include . Non è perfetto ma elimina il "ovvio" include inutili. Sbarazzarsi di questi fa molto per ripulire il codice.

Gli script sono accessibili direttamente su GitHub.

PC Lint di Gimpel Software può segnalare quando è stato incluso un file di inclusione altro di una volta in un'unità di compilazione , ma non riesce a trovare i file include che non sono necessari nel modo che stai cercando.

Modifica: può. Vedi la risposta di itsmatt

CLion , l'IDE C / C ++ di JetBrains, rileva che le ridondanti includono out-of-the -scatola. Questi sono disattivati ??nell'editor, ma ci sono anche funzioni per ottimizzare include nel file corrente o nell'intero progetto .

Ho scoperto che paghi per questa funzionalità però; CLion impiega un po 'di tempo per scansionare e analizzare il tuo progetto quando viene caricato per la prima volta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top