7.14 関数の記憶クラス
7.14.1 関数の可視性
関数は、変数と異なり内部レベルというものが存在しません。つまり、関数は常にグローバルな寿命を持ち、同一のファイル内であればどこからでも参照することができます。もちろん、関数を呼び出すためにはそれよりも前にプロトタイプ宣言されていなければならないことは「4.3 関数の宣言」で解説したとおりです。
しかし、変数同様に複数のファイルを同時にコンパイルする場合、関数名の競合という問題が発生します。実は、これを解決するために関数にも記憶クラスが存在しているのです。関数に指定できる記憶クラスは static と extern のいずれかです。
static 記憶クラスを持つ関数は、その関数が定義されているファイル内の関数からのみ呼び出すことができます。他のファイルの関数から static 関数を呼び出すことはできません。逆に extern 記憶クラスを持つ関数は、他のファイルの関数から呼び出すことができます。これまでのように、関数の記憶クラスを省略した場合は extern が暗黙的に採用されます。
#include <stdio.h> void Function1(void); void Function2(void); int main() { /*Function1(); /*エラー*/ Function2(); return 0; }
static void Function1() {} extern void Function2() {}
コード1とコード2を同時にコンパイルした場合、main() 関数からは Function2() を呼び出すことは可能ですが、Function1() 関数はコード1からは見えないため、呼び出すことはできません。コメント化されている Function1() のコメントを解除してコンパイルすればエラーになることが確認できます。Function1() 関数は static 記憶クラスを持つため、外部のファイルからは見えません。
これは、局所的に用いる特定の処理に特化した関数を作成する時に便利です。特定のファイル内の、特定の処理に特化した独立性の低い関数の場合は、名前の競合を避けるために static 記憶クラスを指定することが推奨されます。