マクロは関数呼び出しを伴わないため、(推定上)より効率的です。ポインターオフセットルックアップのみを含むため、より簡単に最適化できます。
関数呼び出しは、プログラムがマクロ定義なしでコンパイルされた場合でも、同じライブラリに対するリンクを可能にします-異なるヘッダーでコンパイルされた場合、またはソースファイル内の不正な宣言でコンパイルされた場合。たとえば、マクロを持たない誰かの「改善された」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);