#include ディレクティブは、コンパイル前にヘッダー ファイルの内容をソース コードに配置することになります。ね?
それでは、コードで printf() 関数を使用しているだけだとしましょう。したがって、コンパイル後とリンクの間に、ヘッダー ファイルからインクルードされたすべての関数実装を削除し、実行可能ファイルのインポート テーブルに printf() 関数実装のみを挿入する何かが発生する必要があります。ソースでコンパイルされました。それについて説明してもらえますか?
printf
関数は実際にはヘッダー ファイルにはありません。リンカーによって実行可能ファイルに自動的にリンクされるライブラリにあります。
ヘッダー ファイルには、関数のプロトタイプのみを含める必要があります。つまり、関数の宣言であり、定義は含めないでください。また、ヘッダー ファイルに関数定義がないため、それらのコードは実際には生成されず、コンパイラは、実際に呼び出す関数のみが生成されたオブジェクト ファイルにエントリを取得するようにして、リンカがそれを認識できるようにします。
C ヘッダー ファイルで宣言された関数プロトタイプは、コンパイル時の制約として機能します。パラメータの正しい数とそれらのパラメータの正しいタイプを識別します。このような制約の検証は、コンパイル フェーズ (つまり*.c -> *.o
) で行われます。
(静的) リンク フェーズでは、オブジェクト ファイルごとにプログラミング ライブラリから未使用のバイナリ オブジェクトを削除します。プログラミング ライブラリはバイナリ オブジェクト ファイル (*.o) のアーカイブであり、それぞれに関数や定数などのコレクションの実装が含まれていますprintf
。オブジェクト ファイル) がプログラムにリンクされます。その他の未使用のオブジェクト ファイルは、リンク時の最適化として削除されます。