Funkcje śródwierszowe a makra
Mimo że wbudowane funkcje są podobne do makr (ponieważ kod funkcji jest rozwijany w punkcie wywołania w czasie kompilacji), wbudowane funkcje są analizowane przez kompilator, tymczasem makra są rozwijane przez preprocesor.W rezultacie istnieje kilka istotnych różnic:
Wbudowane funkcje przestrzegają wszystkich protokołów bezpieczeństwa typu wymuszanych na normalnych funkcjach.
Wbudowane funkcje są określone za pomocą tej samej składni, co wszelkie inne funkcje, chyba że zawierają one słowo kluczowe inline w deklaracji funkcji.
Wyrażenia przekazywane jako argumenty do funkcji wbudowanych są obliczane jeden raz.W niektórych przypadkach, wyrażenia przekazywane jako argumenty do makr mogą być obliczane więcej niż jeden raz.
Przykład
W poniższym przykładzie pokazano makro, które konwertuje małe litery na wielkie litery:
// inline_functions_macro.c
#include <stdio.h>
#include <conio.h>
#define toupper(a) ((a) >= 'a' && ((a) <= 'z') ? ((a)-('a'-'A')):(a))
int main() {
char ch;
printf_s("Enter a character: ");
ch = toupper( getc(stdin) );
printf_s( "%c", ch );
}
Zamiar wyrażenia toupper(getc(stdin)) to odczytanie znaku z urządzenia konsoli (stdin) oraz, jeśli konieczne, konwertowanie na wielką literę.
Z powodu implementacji makra, getc jest wykonywane raz w celu ustalenia, czy znak jest większy lub równy "a", a raz w celu ustalenia, czy jest mniejszy lub równy "z". Jeśli jest w tym zakresie, getc jest wykonywane ponownie, aby przekonwertować wybrany znak na wielką literę.Oznacza to, że program czeka na dwa lub trzy znaki, gdy powinien czekać tylko na jeden.
Funkcje wbudowane rozwiązują wcześniej opisany problem:
// inline_functions_inline.cpp
#include <stdio.h>
#include <conio.h>
inline char toupper( char a ) {
return ((a >= 'a' && a <= 'z') ? a-('a'-'A') : a );
}
int main() {
printf_s("Enter a character: ");
char ch = toupper( getc(stdin) );
printf_s( "%c", ch );
}