C の静的関数を使用すると、その特定の関数をそのファイルの範囲内でのみ呼び出すことができることを理解しています。私が興味を持っているのは、これがどのように発生するかです。メモリの特定の部分に配置されているのか、それともコンパイラがその関数に特定の操作を適用しているのか。これと同じプロセスをアセンブリの関数呼び出しに適用できますか?
4 に答える
関数を宣言しても、他の翻訳単位から呼び出されるstatic
のを実際に防ぐことはできません。
関数が他の翻訳単位から名前で参照(リンクstatic
) されるのを防ぎます。これにより、その関数への直接呼び出し、つまり「名前による」呼び出しの可能性がなくなります。これを実現するために、コンパイラは、変換単位からエクスポートされた外部名のテーブルから関数名を単純に除外します。それ以外には、静的関数について特別なことはまったくありません。
他の方法で他の翻訳単位からその関数を呼び出すこともできます。たとえば、何らかの方法static
で他の翻訳単位の関数へのポインターを取得した場合、そのポインターを介して呼び出すことができます。
他のものにリンクされるのを防ぐオブジェクトの名前テーブルにはなりません。
関数およびその他の名前は、オブジェクト ファイルにシンボルとしてエクスポートされます。リンカーはこれらのシンボルを使用して、リンク時にあらゆる種類のダングリング参照 (別のファイルで定義された関数の呼び出しなど) を解決します。宣言するとstatic
、単にシンボルとしてエクスポートされません。したがって、他のファイルによって取得されることはありません。関数ポインターがあれば、別のファイルから呼び出すこともできます。
実際、それは反対です。関数が静的でない場合、その名前はオブジェクト ファイルのどこかに書き込まれます。リンカーは、この関数を使用して他のオブジェクト ファイルをその関数のアドレスにリンクするために使用できます。
関数が宣言されている場合static
、コンパイラは単に名前をそこに入れません。