Cコンパイラは、.aファイルに静的にリンクするときに未使用の関数を削除しますか?

Cコンパイラは、.aファイルに静的にリンクするときに未使用の関数を削除しますか?

main.cに静的にリンクされたライブラリがあるとしますlibmine.a。ライブラリへの静的リンクのため、ライブラリ関数はコンパイル時にデフォルトの実行可能ファイルに含まれます。

libmine.a未使用の関数が提供されている場合、main.cコンパイラ(GCCなど)はこれらの関数を破棄しますか?

この質問は、静的ライブラリを使用すると、実行可能ファイルがより大きくなるという「共通メッセージング」に触発されたので、コンパイラが少なくともアーカイブで使用していないコードを削除するかどうか疑問に思います。

ベストアンサー1

デフォルトでは、リンカはオブジェクトファイル全体を処理します。あなたの例では、実行可能ファイルには、最終的にmain.c()のコードと、使用されるすべてのmain.o機能を提供(配信)するために必要なすべてのオブジェクトファイルlibmine.a(オブジェクトファイルのアーカイブ)が含まれますmain.c

したがって、リンカーに必ずしも以下を含める必要はありません。みんなただし、libmine.a利用可能な粒度は関数(デフォルト)ではなく、オブジェクトファイル(厳密にはセクション)です。その理由は、.c特定のファイルをオブジェクトファイルにコンパイルすると、ソースコードの情報が失われるためです。特に、関数の終わりは保存されず、関数の開始のみが保存され、複数の関数を組み合わせることができるためです。 、機能を使用していないときに実際に削除できる項目をオブジェクトファイルで決定することは困難です。

ただし、コンパイラとリンカーは、必要な追加情報にアクセスできれば、より良い操作を実行できます。たとえば、1980年代のMacのLightspeedCプログラミング環境では、プロジェクトをライブラリとして使用することができ、その場合は完全なソースコードがあったため、実際に必要な機能のみを含めることになりました。

より近代的なシステムでは、リンカが関数を個別に処理できるようにするオブジェクトファイルを生成するようにコンパイラに指示できます。 GCCを使用してオプションが有効なファイルをビルドし、.o最終プログラムをそのオプションに関連付けます。これは、特定のクラスの最適化を防止するのに特に影響します。-ffunction-sections -fdata-sections--gc-sectionsGCCで使用されていない関数を破棄します。もっと学ぶ。

最新のコンパイラとリンカで利用可能なもう1つのオプションは、リンク時間の最適化です-flto。最適化が有効になっている場合(例えば -O2オブジェクトファイルをコンパイルするとき、リンカには結果のバイナリに使用されていない関数は含まれません。そうでなくても-ffunction-sections -fdata-sections

おすすめ記事