160 likes | 272 Views
Il preprocessore. Il preprocessore. Viene invocato dal gcc prima della compilazione vera e propria ( cpp ) Esegue delle manipolazioni testuali sul file sostituisce nomi con testo elimina e inserisce testo Le righe di codice che iniziano per # sono direttive per il cpp
E N D
Il preprocessore • Viene invocato dal gcc prima della compilazione vera e propria (cpp) • Esegue delle manipolazioni testuali sul file • sostituisce nomi con testo • elimina e inserisce testo • Le righe di codice che iniziano per # sono direttive per il cpp • Il risultato del preprocessore si può vedere con gcc -E
Il preprocessore : direttive • #include <file> • #include “file” • sono rimpiazzate dal contenuto del file • #define nome testo • macro senza parametri • tutte le occorrenze di nome sono rimpiazzate dal testo specificato
Macro con parametri • È possibile definire macro con parametri! • #define nome(a1,…,an) testo • in questo caso il nome simbolico da sostituire può essere specializzato ad ogni occorrenza della macro es. #define PRODOTTO(X,Y) (X)*(Y) … a = PRODOTTO(a+1,b); c = PRODOTTO(x+y,k); …
Macro con parametri (2) • Dopo la passata del pre-processore ... /* la linea della define non c’e’ piu’ */ … a = (a+1)*(b); c = (x+y)*(k); … • Le parentesi nella definizione sono importanti per avere la precedenza corretta degli operatori!
Macro con parametri (3) • Una definizione scorretta sarebbe. #define PRODOTTO(X,Y) X*Y … a = PRODOTTO(a+1,b); c = PRODOTTO(x+y,k); …
Macro con parametri (4) • Risultato dopo il pre-processore... /* la linea della define non c’e’ piu’ */ … a = a+1*b; c = x+y*k; …
Macro e Funzioni • Attenzione alla differenza fra macro con parametri e funzioni ! • (1) Le macro sostituiscono testo per testo • (2) una macro viene espansa a tempo di compilazione e non genera chiamate in fase di esecuzione
Macro e Funzioni (2) • Attenzione alla differenza fra macro con parametri e funzioni ! • (3) Le macro non sono tipate! Funzionano indipendentemente dal tipo degli argomenti #define PRODOTTO(X,Y) X*Y double a,b; int x,y,k,c; … a = PRODOTTO(a+1,b); c = PRODOTTO(x+y,k);
Macro su più righe ... • Attenzione : il testo da sostituire va da X fino alla fine della riga #define PRODOTTO(X,Y) X*Y … • Per fare macro su più righe usare backslash(\) #define PRODOTTO(X,Y) \ X*Y
Compilazione condizionale • #if #ifdef #ifndef #endif : • sono direttive al preprocessore che permettono di includere selettivamente alcuni pezzi del codice durante la compilazione • #if #if espr_cond #endif Questa zona viene inclusa solo se espr_cond è verificata (cioè se è diversa da 0)
Compilazione condizionale (2) • #if #ifdef #ifndef #endif : • es: un modo rapido per commentare un’area che ha già dei commenti /*…*/ • il C non ammette commenti annidati #if 0 #endif Questa zona non viene mai inclusa
Compilazione condizionale (3) • #if #ifdef #ifndef #endif : • #ifdef nometesta se nome è già stato definito con una #define #ifdef nome #endif Questa zona viene inclusa solo se nome è stato definito con una #define
Compilazione condizionale (4) • #if #ifdef #ifndef #endif : • #ifndef nometesta se nomenon è già stato definito con una #define #ifndef nome #endif Questa zona viene inclusa solo se nome non è già stato definito con una #define
Compilazione condizionale (5) • #if #ifdef #ifndef #endif : • quando si usano ? • Es. escludere condizionalemnte il codice di debugging • se ho finito il debugging tolgo la #define #define DEBUG …. #ifdef DEBUG #endif assert(..) printf(..)
Compilazione condizionale (6) • #if #ifdef #ifndef #endif : • questo si può fare utilizzando gcc -D gcc -Dnome=val file.c inserisce all’inizio di file.c (prima del preprocessing) #define nome val • in questo caso (1) durante il debugging uso -D (2) quando il debugging è finito compilo senza -D ed il codice di test non viene generato