Макрос (мабуть) є більш ефективним, оскільки він не включає виклик функції. Його можна оптимізувати простіше, оскільки це просто включає пошук зміщення вказівника.
Виклик функції дозволяє пов'язувати одну і ту ж бібліотеку, навіть якщо програма була скомпільована без визначення макросу - якщо вона була складена з іншим заголовком, або просто з неправдивим оголошенням всередині вихідного файлу. Якщо, наприклад, у вас є компілятор, який має чиюсь "покращену" версію ctype.h, яка не мала макросу, функція все одно існуватиме під час виконання для використання.
Якщо ми подивимось на стандарт:
c99
7.1.4 Використання функцій бібліотеки
Будь-яка функція, оголошена в заголовку, може бути додатково реалізована як макрос, визначений у функції, визначений у заголовку, тому якщо функція бібліотеки явно оголошена при включенні її заголовка, для забезпечення декларації не можна використовувати один із наведених нижче методів. впливає такий макрос. Будь-яке макрозначення функції може бути придушене локально, включивши ім’я функції в дужки, тому що за ім'ям не йде ліва дужка, що вказує на розширення імені функції макроса. З тієї ж синтаксичної причини дозволено приймати адресу функції бібліотеки, навіть якщо вона також визначена як макрос.
Це означає, що якщо ви пишете:
int b = (isdigit)(c);
або
int (*f)(int) = &isdigit;
int b = f(c);
то ви викликаєте фактичну функцію, а не макрос. Ви також можете юридично написати:
#undef isdigit
int b = isdigit(c);
або (у вихідному файлі, що не має #include <ctype.h>
прямого або перехідного періоду):
extern int isdigit(int);
int b = isdigit(c);