C言語で関数のエイリアス
後から関数の実装を置き換えたいような場合に、その関数のエイリアス(別名)を定義して、前もってエイリアスでプログラムを組んでおくと置き換えの手間が少なくなります。C言語で、関数のエイリアスを実装するにはどのような方法があるでしょうか。ちょっと考えてみました。以下サンプルプログラム。
#include <stdio.h> void foo(int a) { printf("foo: %d\n", a); } /* foo()へのエイリアス その1 従来のマクロ版 */ #define foo_alias1 foo /* foo()へのエイリアス その2 従来のマクロ版(引数あり) */ #define foo_alias2(a) foo(a) /* foo()へのエイリアス その3 C99の可変長引数マクロ版 */ #define foo_alias3(...) foo(__VA_ARGS__) /* foo()へのエイリアス その4 関数ポインタ版 */ void (*foo_alias4)(int a) = foo; /* foo()へのエイリアス その5 インライン関数版 */ inline void foo_alias5(int a) { foo(a); } int main(int argc, char *argv[]) { foo(123); foo_alias1(123); foo_alias2(123); foo_alias3(123); foo_alias4(123); foo_alias5(123); return 0; }
gcc version 3.3.3 (NetBSD nb3 20040520)で、gcc -Eの出力。
... int main(int argc, char *argv[]) { foo(123); foo(123); foo(123); foo(123); foo_alias4(123); foo_alias5(123); return 0; }
gcc -S -O2の出力。
... call foo movl $123, (%esp) call foo movl $123, (%esp) call foo movl $123, (%esp) call foo movl $123, (%esp) call *foo_alias4 # => foo_alias4 movl $123, (%esp) call foo # => foo_alias5 ...
その1は、関数のとこ以外も置き換えてしまうからちょっと乱暴すぎでしょうか(まぁ間違えないだろうという割切りもありか…)。C99を使用可能なら、その3。インライン関数の最適化が見込めるなら、その5かなぁ。