Funzioni Inline

In C, non era facile definire macro-funzioni. L'uso della direttiva #define non è semplice. C++ fornisce un modo migliore di creare delle funzioni macro.

Se dichiari una funzione "inline", allora il codice sarà riprodotto nel punto di chiamata ognivolta che chiami la funzione. Attenzione che è necessario definire il codice della funzione prima della sua prima chiamata, altrimenti un compilatore potrebbe non essere in grado di espanderlo.

Ndt: Infatti il codice delle funzioni inline deve essere espanso, non deve essere generata solo una chiamata (questa è la differenza!)

Questo è il motivo per cui il codice delle funzioni inline è generalmente messo nel file header che dichiara le funzioni inline stesse.

inline int addition (int a, int b)
{
  return a + b;
}
Ma puoi anche definire la funzione in due passi:
inline int addition (int a, int b);   // qui la keyword inline è opzionale
... // qui però addition non deve ancora essere usata
inline int addition (int a, int b)
{
  return a + b;
}
Usare le funzioni inline probabilmente sarà più efficiente, perchè la maggior parte dei compilatori C++ prima sostituirà il codice, e poi lo ottimizzerà. Ma la dimensione del codice può aumentare di parecchio. Perciò è raccomandabile usare inline solo per piccole funzioni (costruttori e operatori di classe sono degli ottimi esempi che vedremo).

Ecco un esempio di codice per quelli che non vedono la differenza tra le funzioni inline e una #define:

#define SQUARE(x) ((x) * (x))
int a = 2;
int b = SQUARE (a++);
   // alla fine: a = 4 e b = 2 * 3 = 6. Sorpreso ?!

inline int square (int x)
{
  return x * x;
}

int c = 2;
int d = square (c++);
   // alla fine: c = 3 e d = 2 * 2 = 4. Risultati corretti come ci aspettavamo !!
Nota: con il compilatore C della GNU (GCC) succede una cosa curiosa quando si chiama la macro SQUARE(a++): il risultato in b è corretto (virtù di GCC che farà felice tutti i programmatori C), però il valore finale di a è ancora 4 e non 3. Tuttavia è possibile risolvere una volta per tutte anche questo problema usando un paio di estensioni del GNU C, che sono i Naming Types e le Statement Exprs. Ecco la soluzione:
/* questo è GNU-specific :) */
#define SQUARE(x) \
  ({typedef _tx = (x); \
    _tx _x=(x); _x*_x; })
In questo modo x viene valutato solo una volta. Per saperne di più sulle estensioni C e C++ di GCC digitate al prompt:
info gcc "C Extensions"
oppure
info gcc "C++ Extensions"

C++