risorse | metriche C++
Da tempo sto valutando l'idea di integrare il processo di build di un progetto C++ di qualche decina di migliaia di righe con una attività automatica di monitoraggio della «qualità» del codice sorgente. Ho dapprima introdotto un'analisi statica del codice, ad opera del programma gratuito open-source Cppcheck: avviato prima della fase di compilazione, causa l'interruzione della procedura di build nel caso abbia individuato uno o più errori. Vorrei raffinare quest'attività raccogliendo ora alcune metriche del codice, per far emergere potenziali criticità del progetto e individuare le aree che necessitano di refactoring. Se le misure raccolte vengono archiviate sistematicamente, risulterà semplice valutare a posteriori l'effetto delle modifiche.
L'individuazione di una metrica fuori tolleranza non causa l'interruzione della procedura di build. Scopo dell'integrazione à fissare nel tempo lo stato del codice – sfruttando la produzione di una nuova versione degli artefatti come «orologio» – per osservare l'andamento della qualità del codice all'evolversi del progetto.
Tra le varie possibilità, ho deciso di concentrarmi su CCCC e Source Monitor.
CCCC è un programma open-source, gratuito e multi-piattaforma. Riconosce sorgenti ADA, C, C++ e Java. Ricava le seguenti metriche:
Le metriche di modulo comprendono un sottoinsieme di quelle di progetto (LOC, COM, MVG, L_C, M_C), oltre alle seguenti, classificate per tipologia:
Le metriche di metodo comprendono un sottoinsieme di quelle di progetto: LOC, COM, MVG, L_C, M_C.
CCCC attribuisce ad ogni metrica una soglia di attenzione «media» e una «alta»; i dati raccolti sono etichettati come rientranti in un ambito di normalità, nella zona d'attenzione media o in quella alta conformemente ai valori assunti rispetto ai valori di soglia. In assenza di specifiche configurazioni, CCCC utilizza le seguenti soglie:
media | alta | |
---|---|---|
LOC (funzione) | 30 | 100 |
LOC (modulo) | 500 | 2000 |
MVG (funzione) | 10 | 30 |
MVG (modulo) | 200 | 1000 |
M_C | 5 | 10 |
L_C | 7 | 30 |
FI | 12 | 20 |
FO | 12 | 20 |
IF4 | 100 | 1000 |
WMC1 | 30 | 100 |
WMCv | 10 | 30 |
DIT | 3 | 6 |
NOC | 4 | 15 |
CBO | 12 | 30 |
CCCC si attende di ricevere l'elenco dei file da analizzare sulla linea di comando o sullo stream di input. I risultati dell'analisi sono salvati in una directory ad hoc, di norma .cccc
. Le metriche di progetto e di modulo si trovano nel file cccc.xml
, mentre quelle di metodo sono raggruppate per modulo di appartenenza e salvate in un file dedicato. Lo script seguente di occupa di analizzare tutti i file presenti nelle cartelle passate sulla linea di comando:
rem cccc.cmd @echo off if "%1"=="" echo Usage: %~n0 source-folders && exit /b %ERROR% set PROGRAMFILES32=%ProgramFiles(x86)% if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMFILES32=%ProgramFiles% set CCCC="%PROGRAMFILES32%\CCCC\cccc.exe" set FILE_LIST=%TEMP%\cccc.lst echo. >nul 2>%FILE_LIST% :loop if "%1"=="" goto done dir /s /b %1 >> %FILE_LIST% shift goto :loop :done set REPORT_FOLDER=.\.cccc type %FILE_LIST% | %CCCC% --outdir=%REPORT_FOLDER% - >nul 2>&1 del /q %FILE_LIST% >nul 2>&1 rem TODO: time to analyze the report! rd /q /s %REPORT_FOLDER% >nul 2>&1
CCCC non è in grado di gestire distintamente moduli omonimi: classi con lo stesso nome, poste in namespace diversi, sono trattate come definizioni parziali di un'unico modulo.
Source Monitor è un programma closed-source gratuito che gira su Windows. Riconosce sorgenti C, C++, C#, Delphi, HTML, Java, VB.NET e Visual Basic. La versione in prova, 3.4.0.283, limitatamente al C/C++, fornisce le seguenti metriche:
Source Monitor può archiviare le metriche raccolte in una sequenza di checkpoint; ciò consente di monitorare l'evoluzione del codice nel tempo.
L'analisi dei sorgenti avviene molto rapidamente: su un PC equipaggiato con una CPU quad-core a 3GHz e 8GB di RAM, si raggiungono velocità dell'ordine delle centinaia di migliaia di linee al secondo.
minimo | massimo | |
---|---|---|
Lines | - | - |
Statements | - | - |
Percent branch statements | - | - |
Percent lines with comments | 15 | 25 |
Classes defined | - | - |
Methods implemented per class | 4 | 20 |
Average statements per method | 5 | 10 |
Maximum complexity | 2 | 8 |
Maximum block depth | 3 | 6 |
Average block depth | 1.0 | 2.5 |
Average complexity | 2.0 | 4.5 |
Functions | - | - |
Il programma è richiamabile da linea di comando; il manuale a corredo del programma illustra chiaramente questa modalità di invocazione. I risultati in questo caso vengono salvati a scelta in formato XML o CSV. L'integrazione di Source Monitor nella procedura di build avviene per mezzo di due file di supporto:
rem source-monitor.cmd @echo off if "%1"=="" echo Usage: %~n0 project-name && exit /b %ERROR% set PROGRAMFILES32=%ProgramFiles(x86)% if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMFILES32=%ProgramFiles% set SOURCEMONITOR="%PROGRAMFILES32%\SourceMonitor\SourceMonitor.exe" set SOURCEMONITOR_CMD="%~dp0\%1.xml" %SOURCEMONITOR% /S %SOURCEMONITOR_CMD% rem TODO: time to analyze the report! rem remove project file del /q %TEMP%\%1.smp 1> nul 2>&1
<sourcemonitor_commands> <log_all_to_console /> <command> <project_file>%TEMP%\PROJECT.SMP</project_file> <project_language>C++</project_language> <modified_complexity>true</modified_complexity> <source_directory>SOURCES-DIRECTORY</source_directory> <source_subdirectory_list> <exclude_subdirectories>false</exclude_subdirectories> <source_subtree>include\</source_subtree> <source_subtree>sources\</source_subtree> </source_subdirectory_list> <parse_utf8_files>True</parse_utf8_files> <checkpoint_name>baseline</checkpoint_name> <show_measured_max_block_depth>True</show_measured_max_block_depth> <file_extensions>*.h,*.cpp</file_extensions> <include_subdirectories>true</include_subdirectories> <export> <export_file>%TEMP%\PROJECT-METRICS.XML</export_file> <export_type>1 (export project summary in XML format)</export_type> <export_option>3</export_option> </export> </command> </sourcemonitor_commands>
Salta immediatamente agli occhi l'assenza di misure relative al grado di accoppiamento dei moduli.
I dati esportati non recano alcuna indicazione circa il rispetto delle soglie di attenzione, il che implica la necessità di un meccanismo di sogliatura esterno nel caso si desideri evidenziare le entità fuori norma.
Per ottenere le statistiche in formato CSV, è necessario comandare due esportazioni distinte, una per quelle di progetto, l'altra per quelle di metodo – il formato CSV non permette di ragguppare statistiche strutturalmente diverse all'interno dello stesso file.
Un ultimo aspetto da considerare è che, nella modalità interattiva, manca un meccanismo per individuare rapidamente le aree critiche: il programma fornisce, alla granularità del file, una rappresentazione grafica dei parametri rispetto ai limiti impostati, ma non fornisce alcun criterio di selezione dei file fuori tolleranza.
Pagina modificata il 27/05/2013