2009-12-10 11 views
19

Sto provando a rimuovere le funzioni che non sono utilizzate da un progetto C++. Col passare del tempo è diventato gonfio e sto cercando di rimuovere le funzioni che non vengono utilizzate affatto.Scopri se una funzione è chiamata all'interno di un progetto C++?

Ho tutti i progetti in un file di soluzione in Visual Studio, ma io uso cmake in modo da poter generare file di progetto per un altro IDE, se necessario (motivo per cui questo non è codificato con visual-studio).

Esiste qualcosa del genere? Dove analizzerà la fonte e dirmi quali funzioni non vengono chiamate. Ho visto PC-Lint menzionato in alcune domande qui, ma questo non sembra farlo.

Quello che voglio veramente fare è chiamare "Trova tutti i riferimenti" su ogni funzione e rimuovere le funzioni non chiamate, ma farlo manualmente richiederebbe troppo tempo.

+0

1 ho avuto lo stesso problema: un progetto legacy non hanno file di progetto/soluzione controllati in, come si può collegare questi progetti senza dipendere dalla ricerca del SO (e dalla ricerca di Windows fa schifo) ... –

+0

Vorrei che qualcuno potesse semplicemente avere il nome di una soluzione open source per questo. – BlueTrin

+0

Di solito in questi casi non faccio commenti sull'implementazione (corpo) della funzione, e vedo se questo collega – valdo

risposta

9

Utilizzare __declspec(deprecated) davanti alla dichiarazione di funzione che si desidera eliminare. Ciò genera avvisi di compilazione se tale funzione viene effettivamente utilizzata in fase di compilazione.

+0

Non lo sapevo, ci penserò sicuramente di più. – Joe

+0

Questa è la soluzione che ho intenzione di usare così contrassegnerò questa come risposta. Funziona bene per me perché _declspec (dllimport deprecato) funziona. #define _declspec (dllimport) vs _declspec (dllexport) così posso solo modificare un posto per dll e vedere cosa viene visualizzato. Tutto appare deprecato almeno una volta perché tutto ha un corpo. Ho usato python per analizzare l'output dal compilatore e creare un istogramma di quante volte ogni classe/funzione è deprecata. Poi guardo quelli con i numeri più bassi più da vicino. – Joe

0

Suppongo che il modo più semplice sia quello di rimuovere una funzione (o classe, variabile, qualsiasi altra cosa si possa ritenere non necessaria) e quindi verificare se compila. Se la funzione viene utilizzata, durante l'operazione di ricostruzione verrà visualizzato un errore di compilazione o di collegamento.

In genere è necessario rimuovere la definizione anziché la dichiarazione, altrimenti con funzioni come funzioni sovraccaricate e modelli specializzati potrebbe compilare e collegarsi a uno degli altri, senza causare un errore ma modificando il comportamento del programma. Rimuovendo la definizione, il compilatore vede ancora la dichiarazione, ma il linker non riuscirà a collegarlo.

Gli articoli dichiarati ma non definiti non causano un errore se non utilizzati, poiché il linker non tenterà mai di collegarsi ad essi.

+2

Incrocio le dita non è caricato dinamicamente ... –

+1

Se conosci la struttura del tuo progetto abbastanza bene da sapere che la funzione non è Si fa riferimento dinamicamente (cioè c'è una ricerca di simboli per la funzione in fase di esecuzione), quindi penso che questa sia la soluzione migliore. È quello che faccio. – Omnifarious

+4

Incrocio di dita che non ci vogliono 30 minuti per costruire il progetto. –

3

Sembra che tu abbia bisogno di uno strumento di copertura del codice. C'è un elenco di loro in questo wikipedia article.

+3

Perché? Nessun codice di test può esistere. – reinierpost

+1

Nessun codice di test esiste. Uno strumento di copertura del codice non funzionerà perché non avremmo idea se colpiamo ogni caso. – Joe

+0

Gli strumenti di copertura del codice non richiedono necessariamente un codice di test specifico: alcuni possono essere eseguiti su un codice normale in un ambiente di produzione. –

3

L'eccellente (e gratuito) strumento di analisi statica del monitor Sorgente, da http://www.campwoodsw.com/ può fornire il conteggio del numero di chiamate a un metodo, che ritengo sia quello che si desidera.

Modifica: Sembra essere la mia serata per il fallimento. La metrica delle chiamate in realtà non fa ciò che pensavo facesse. Tuttavia, SM è uno strumento eccellente, quindi spero che portarlo all'attenzione della gente abbia fatto del bene!

+0

Ho provato Source Monitor e penso che le statistiche di chiamata per un metodo non siano il numero di volte in cui è stato chiamato questo metodo, ma il numero di chiamate ad altri metodi che questo metodo sta facendo. Per favore qualcuno mi corregga se ho torto. – BlueTrin

+0

Sì, sembri essere corretto. Mi dispiace, non è una metrica, in realtà uso me stesso. –

1

Se il codice è abbastanza semplice, l'analisi statica potrebbe funzionare. Tuttavia C++ è molto sensibile al contesto: /. Quindi personalmente non proverei nemmeno a cercare uno strumento nell'area. Almeno non prima che CLANG sia pienamente compatibile con C++: D

Spero che tu abbia dei test unitari, vorrei ottenere Visual Studio per compilare il codice che genera un profilo runtime e quindi coltivare i nomi delle funzioni (con un linguaggio di scripting) da il profilo generato. Se hai coperto tutti i casi d'uso (manualmente o con unit test) nella tua applicazione dovresti essere in grado di identificare le funzioni meno usate (o mai usate). Quindi puoi usare il bulbo oculare mark-one per ridurre la base di partenza.

Non c'è nulla come farlo manualmente però: D

1

Visual Studio può generare grafici di chiamata, che mostra 'chiamato-by' per ogni funzione. Doxygen farà lo stesso se non vuoi usare Visual Studio.

Tuttavia, entrambi questi metodi non riescono a rilevare una funzione chiamata tramite un puntatore, ma che normalmente dovrebbe essere facile da controllare manualmente.

+0

+1 per far apparire i puntatori di funzione, anche se non sono d'accordo sul fatto che sarà sempre facile da controllare manualmente. l'unico problema che ho con l'intero concetto è che, poiché i possibili percorsi di controllo saranno esponenziali in numero relativo ai moduli che hai effettivamente scritto, è probabilmente impossibile rimuoverli con certezza del 100% di sicurezza a meno che TUTTE le funzioni siano collegate staticamente. –

+0

Ho detto che sarebbe * normalmente * facile in base al fatto che i puntatori di funzione non sono spesso ampiamente utilizzati all'interno di una base di codice. Intendevo in termini di sforzo, non necessariamente di complessità; Sto assumendo una certa familiarità con il codice; per esempio se fosse il tuo codice, probabilmente sapresti se e dove hai usato i puntatori di funzione! – Clifford

+0

abbastanza giusto. Ho davvero messo le parole in bocca lì. –

1

Se si desidera conoscere, in modo dinamico, quali funzioni vengono utilizzate, è possibile ottenere il compilatore (vC++) per inserire i hook callcap e quindi utilizzarli per scaricare informazioni sull'utilizzo.

Questo potrebbe essere un utile complemento agli approcci basati sull'analisi statica, poiché vedrà ogni pezzo di codice inserito durante l'esecuzione (indipendentemente da come l'esecuzione arriva lì).

Vedere http://msdn.microsoft.com/en-us/library/ms254291(VS.80).aspx per informazioni sugli hook del profilo di chiamata in Visual Studio.

2

Sono abbastanza sicuro che matematicamente, questo non può essere fatto nel caso generale. Se si accettano puntatori di ricorsione e funzione (o funzioni di prima classe), si finisce in una riduzione piuttosto semplice del problema di interruzione.

Certo, questo essere un caso che non avete mai avere a che fare con, ma si deve sapere abut esso ...

+0

questo è il punto che stavo facendo nel mio commento alla risposta di clifford. hai postato la risposta, ottieni i punti :) .. +1 –

Problemi correlati