Makro, bir işlev çağrısı içermediğinden (varsayılan olarak) daha verimlidir. Sadece bir işaretçi ofseti araması içerdiğinden daha kolay optimize edilebilir.
İşlev çağrısı, program makro tanımı olmadan derlenmiş olsa bile - farklı bir üstbilgi ile derlenmişse veya yalnızca kaynak dosya içinde hileli bir bildirimle aynı kütüphaneye bağlanmaya izin verir. Örneğin, birinin ctype.h dosyasının makroyu içermeyen "geliştirilmiş" sürümüne sahip bir derleyiciniz varsa, işlev çalışma zamanında kullanım için var olmaya devam eder.
Standarda bakarsak:
c99
7.1.4 Kütüphane fonksiyonlarının kullanımı
Üstbilgide bildirilen herhangi bir işlev ek olarak üstbilgide tanımlanan işlev benzeri bir makro olarak da uygulanabilir, bu nedenle bir kitaplık işlevi üstbilgisi dahil edildiğinde açıkça bildirilirse, bildirimin yapılmadığından emin olmak için aşağıda gösterilen tekniklerden biri kullanılabilir böyle bir makrodan etkilenir. Bir işlevin herhangi bir makro tanımı, işlevin adı parantez içine alınarak yerel olarak bastırılabilir, çünkü adın ardından bir makro işlev adının genişlemesini gösteren sol parantez gelmez. Aynı sözdizimsel sebepten dolayı, bir makro olarak tanımlanmış olsa bile bir kütüphane fonksiyonunun adresini almasına izin verilir.
Bu, şöyle yazarsanız:
int b = (isdigit)(c);
veya
int (*f)(int) = &isdigit;
int b = f(c);
makroyu değil, gerçek işlevi çağırıyorsunuz. Ayrıca yasal olarak şunları yazabilirsiniz:
#undef isdigit
int b = isdigit(c);
veya ( #include <ctype.h>
doğrudan veya geçişli olmayan bir kaynak dosyada ):
extern int isdigit(int);
int b = isdigit(c);