Gli strumenti software di solito offrono più funzionalità, ma, come molti di voi concorderanno, non tutte le loro funzionalità sono utilizzate da tutti. In generale, non c'è niente di sbagliato in questo, poiché ogni utente ha le proprie esigenze e utilizza gli strumenti solo all'interno di quella sfera. Tuttavia, è sempre bene continuare a esplorare gli strumenti che utilizzi poiché non sai mai quando una delle loro funzionalità potrebbe tornare utile, risparmiandoti un po' del tuo tempo prezioso nel processo.
Caso in questione:compilatori. Un buon compilatore di linguaggio di programmazione offre sempre una pletora di opzioni, ma gli utenti generalmente conoscono e utilizzano solo un set limitato. In particolare, se sei uno sviluppatore del linguaggio C e utilizzi Linux come piattaforma di sviluppo, è molto probabile che tu utilizzi il compilatore gcc, che offre un elenco infinito di opzioni della riga di comando.
Sai che se vuoi, puoi chiedere a gcc di salvare l'output in ogni fase del processo di compilazione? Conosci il -Muro l'opzione che usi per generare avvisi non copre alcuni avvisi specifici? Esistono molte opzioni di gcc della riga di comando che non sono comunemente utilizzate, ma possono essere estremamente utili in determinati scenari, ad esempio durante il debug del codice.
Quindi, in questo articolo, tratteremo un paio di tali opzioni, offrendo tutti i dettagli richiesti e spiegandoli attraverso esempi di facile comprensione ove necessario.
Ma prima di andare avanti, tieni presente che tutti gli esempi, i comandi e le istruzioni menzionati in questo tutorial sono stati testati su Ubuntu 16.04 LTS e la versione gcc che abbiamo usato è 5.4.0.
Visualizza l'output intermedio durante ogni fase di compilazione
Sai che ci sono, in generale, un totale di quattro fasi che il tuo codice C attraversa quando lo compili usando il compilatore gcc? Si tratta di preelaborazione, compilazione, assemblaggio e collegamento. Dopo ogni fase, gcc produce un file di output temporaneo che viene passato alla fase successiva. Ora, questi sono tutti file temporanei che vengono prodotti e quindi non li vediamo:tutto ciò che vediamo è che abbiamo emesso il comando di compilazione e produce il file binario/eseguibile che possiamo eseguire.
Ma supponiamo, se durante il debug, è necessario vedere come il codice si è occupato, ad esempio, della fase di preelaborazione. Allora, cosa faresti? Bene, la cosa buona è che il compilatore gcc offre un'opzione della riga di comando che puoi usare nel tuo comando di compilazione standard e otterrai quei file intermedi che altrimenti verranno eliminati dal compilatore. L'opzione di cui stiamo parlando è -save-temps .
Ecco cosa dice la pagina man di gcc su questa opzione:
Store the usual "temporary" intermediate files permanently; place
them in the current directory and name them based on the source
file. Thus, compiling foo.c with -c -save-temps produces files
foo.i and foo.s, as well as foo.o. This creates a preprocessed
foo.i output file even though the compiler now normally uses an
integrated preprocessor.
When used in combination with the -x command-line option,
-save-temps is sensible enough to avoid over writing an input
source file with the same extension as an intermediate file. The
corresponding intermediate file may be obtained by renaming the
source file before using -save-temps.
Di seguito è riportato un comando di esempio che ti darà un'idea su come utilizzare questa opzione:
gcc -Wall -save-temps test.c -o test-exec
Ed è così che ho verificato che tutti i file intermedi sono stati effettivamente prodotti dopo l'esecuzione del comando sopra menzionato:
Quindi, come puoi vedere nello screenshot qui sopra, il test.i , test.s e test.o i file sono stati prodotti da -save-temps opzione. Questi file corrispondono rispettivamente alle fasi di preelaborazione, compilazione e collegamento.
Prepara il debug e la profilazione del codice
Sono disponibili strumenti dedicati che consentono di eseguire il debug e di profilare il codice sorgente. Ad esempio, gdb viene utilizzato per scopi di debug, mentre gprof è uno strumento popolare per scopi di profilazione. Ma sai che ci sono specifiche opzioni della riga di comando offerte da gcc per rendere il debug del tuo codice pronto e la profilazione?
Cominciamo con il debug. Per poter utilizzare gdb per il debug del codice, dovrai compilare il tuo codice usando -g l'opzione della riga di comando ha fornito il compilatore gcc. Questa opzione fondamentalmente consente a gcc di produrre le informazioni di debug richieste da gdb per eseguire correttamente il debug del tuo programma.
Nel caso in cui prevedi di utilizzare questa opzione, ti consigliamo di esaminare i dettagli che la pagina man di gcc offre su questa opzione, alcuni dei quali possono rivelarsi vitali in alcuni casi. Ad esempio, quello che segue è un estratto tratto dalla pagina man:
GCC allows you to use -g with -O. The shortcuts taken by optimized
code may occasionally produce surprising results: some variables
you declared may not exist at all; flow of control may briefly move
where you did not expect it; some statements may not be executed
because they compute constant results or their values are already
at hand; some statements may execute in different places because
they have been moved out of loops.
Nevertheless it proves possible to debug optimized output. This
makes it reasonable to use the optimizer for programs that might
have bugs.
Non solo gdb, compilando il tuo codice usando -g l'opzione apre anche la possibilità di utilizzare lo strumento memcheck di Valgrind al massimo delle sue potenzialità. Per coloro che non sono a conoscenza, memcheck viene utilizzato dai programmatori per verificare la presenza di perdite di memoria (se presenti) nel loro codice. Puoi saperne di più su questo strumento qui.
Andando avanti, per poter utilizzare gprof per la profilazione del codice, devi compilare il tuo codice usando -pg opzione della riga di comando. Consente a gcc di generare codice aggiuntivo per scrivere informazioni di profilazione, richiesta da gprof per l'analisi del codice. "Devi utilizzare questa opzione durante la compilazione dei file di origine su cui desideri dati e devi utilizzarla anche durante il collegamento", dice la pagina man di gcc. Per ulteriori informazioni su come eseguire la profilatura del codice utilizzando gprof, vai a questo tutorial dedicato sul nostro sito Web.
Nota :utilizzo di entrambi -g e -pg opzioni è simile al modo in cui -save-temps opzione è stata utilizzata nella sezione precedente.
Conclusione
A meno che tu non sia un professionista di gcc, sono sicuro che hai imparato qualcosa di nuovo con questo articolo. Prova queste opzioni e guarda come funzionano. Nel frattempo, attendi la parte successiva in questa serie di tutorial in cui discuteremo di opzioni della riga di comando di gcc più interessanti e utili.