Cerca nel sito:
ricerca
avanzata

Frasi Celebri...

Siate sempre cortesi con le persone pi? giovani di voi, perch? saranno loro a scrivere di voi.

Cyril Vernon Connolly 

Sondaggio:

Come va la vita con l'Euro?

Ottimo!
Come prima
Fatico ma imparer?
Porc... che macello!

visualizza risultati


 

Funzioni inline

Le funzioni consentono di scomporre in piu` parti un grosso programma facilitandone sia la realizzazione che la successiva manutenzione. Tuttavia spesso si e` indotti a rinunciare a tale beneficio perche` l'overhead imposto dalla chiamata di una funzione e` tale da sconsigliare la realizzazione di piccole funzioni. Le possibili soluzioni in C erano due:

  1. Rinunciare alle funzioni piccole, tendendo a scrivere solo poche funzioni corpose;

  2. Ricorrere alle macro;

La prima in realta` e` una pseudo-soluzione e porta spesso a programmi difficili da capire e mantenere perche` in pratica rinuncia ai benefici delle funzioni; la seconda soluzione invece potrebbe andare bene in C, ma non in C++: una macro puo` essere vista come una funzione il cui corpo e` sostituito (espanso) dal preprocessore in luogo di ogni chiamata. Il problema principale e` che questo sistema rende difficoltoso ogni controllo statico di tipo poiche` gli errori divengono evidenti solo quando la macro viene espansa; in C tutto sommato cio` non costituisce un grave problema perche` il C non e` fortemente tipizzato.
Al contrario il C++ possiede un rigido sistema di tipi e l'uso di macro costituisce un grave ostacolo allo sfruttamento di tale caratteristica. Esistono poi altri svantaggi nell'uso delle macro: rendono difficile il debugging e non sono flessibili come le funzioni (e` ad esempio difficile rendere fattibili macro ricorsive).

Per non rinunciare ai vantaggi forniti dalle (piccole) funzioni e a quelli forniti da un controllo statico dei tipi, sono state introdotte nel C++ le funzioni inline.
Quando una funzione viene definita inline il compilatore ne memorizza il corpo e, quando incontra una chiamata a tale funzione, semplicemente lo sostituisce alla chiamata della funzione; tutto cio` consente di evitare l'overhead della chiamata e, dato che la cosa e` gestita dal compilatore, permette di eseguire tutti i controlli statici di tipo.
Se si desidera che una funzione sia espansa inline dal compilatore, occorre definirla esplicitamente inline:

 

inline int Sum(int a, int b) {
  return a + b;
}

 

La keyword inline informa il compilatore che si desidera che la funzione Sum sia espansa inline ad ogni chiamata; tuttavia cio` non vuol dire che la cosa sia sempre possibile: molti compilatori non sono in grado di espandere inline qualsiasi funzione, tipicamente le funzioni ricorsive sono molto difficili da trattare e il mio compilatore non riesce ad esempio a espandere funzioni contenenti cicli. In questi casi comunque la cosa generalmente non e` grave, poiche` un ciclo tipicamente richiede una quantita` di tempo ben maggiore di quello necessario a chiamare la funzione, per cui l'espansione inline non avrebbe portato grossi benefici. Quando l'espansione inline della funzione non e` possibile solitamente si viene avvisati da una warning.
Si osservi che, per come sono trattate le funzioni inline, non ha senso utilizzare la keyword inline in un prototipo di funzione perche` il compilatore necessita del codice contenuto nel corpo della funzione:

 

inline int Sum(int a, int b);

int Sum(int a, int b) {
  return a + b;
}

 

In questo caso non viene generato alcun errore, ma la parola chiave inline specificata nel prototipo viene del tutto ignorata; perche` abbia effetto inline deve essere specificata nella definizione della funzione:

 

int Sum(int a, int b);

inline int Sum(int a, int b) {
  return a + b;
}                   // Ora e` tutto ok!

 

Un'altra cosa da tener presente e` che il codice che costituisce una funzione inline deve essere disponibile prima di ogni uso della funzione, altrimenti il compilatore non e` in grado di espanderla (non sempre almeno!). Una funzione ordinaria puo` essere usata anche prima della sua definizione, poiche` e` il linker che si occupa di risolvere i riferimenti (il linker del C++ lavora in due passate); nel caso delle funzioni inline, poiche` il lavoro e` svolto dal compilatore (che lavora in una passata), non e` possibile risolvere correttamente il riferimento. Una importante conseguenza di tale limitazione e` che una funzione puo` essere inline solo nell'ambito del file in cui e` definita, se un file riferisce ad una funzione definita inline in un altro file (come, lo vedremo piu` avanti), in questo file (il primo) la funzione non potra` essere espansa; esistono comunque delle soluzioni al problema.
Le funzioni inline consentono quindi di conservare i benefici delle funzioni anche in quei casi in cui le prestazioni sono fondamentali, bisogna pero` valutare attentamente la necessita` di rendere inline una funzione, un abuso potrebbe portare a programmi difficili da compilare (perche` e` necessaria molta memoria) e voluminosi in termini di dimensioni del file eseguibile.

 

successivo
–«  INDICE  »–

 

 

 

 
Powered by paper&pencil (carta&matita ) - Copyright © 2001-2022 Cataldo Sasso