9

sin、cos、acos を呼び出す ac プログラムがあります。コンパイルすると、次のエラーが発生します。

/tmp/ccDfW98S.o: In function `zip_search':
main.c:(.text+0xf30): undefined reference to `sin'
main.c:(.text+0xf45): undefined reference to `sin'
main.c:(.text+0xf66): undefined reference to `cos'
main.c:(.text+0xf7b): undefined reference to `cos'
main.c:(.text+0xf9c): undefined reference to `cos'
main.c:(.text+0xfc6): undefined reference to `acos'
collect2: ld returned 1 exit status

-lm gcc フラグを使用しない場合、これはよくあることです。私はこのフラグを使用しています。私はこのようにGCCを呼び出しています:

gcc -o zipcode-server -lm main.c

私のコンピューターの 1 つでコンパイルすると、これは正常に動作します。私が考えることができる唯一の違いは、これが x86_64 では機能せず、動作するコンピューターが i686 であることです。どちらもUbuntuです。ファイルlibm.aは、動作していないコンピューターに存在し、見つからないというエラーは発生しません。何が原因でしょうか?

4

1 に答える 1

26

-lm後に置く必要がありますmain.c

一般に、複数のライブラリがある場合は、使用順に記述する必要があります。たとえば、ライブラリがライブラリAを使用する場合B-lA -lB.

あなたの場合、コンパイルの結果であるオブジェクトファイルmain.cはライブラリを使用しているmため、-lmその後に来る必要があります。


興味深いことに、これは主に効率上の理由によるものです。このスキームを使用すると、リンカは、引数リストにあるすべての新しいライブラリで現在不明なシンボルを解決し、途中でそのライブラリから新しい不明なシンボルを取得できます。これは、リンカーがライブラリを 1 つずつアクセスできることを意味し、したがって、未知のシンボルを各ライブラリによって提供される少数のシンボルと照合します。

対照的に、リンカは一度にすべてのライブラリからシンボルを読み込み、未知のシンボルの照合を開始できます。ただし、その場合、リンカは非常に多くのシンボルを処理する必要があり、メモリ フットプリントとリンカの実行時間の両方が増加します。

ライブラリは常に依存関係の適切な順序でリンカーに宣言できるため1、リンカーが非効率的な方法を選択する理由はありません。

1 ライブラリは通常、一方が他方を使用するという意味で、一方向の関係を持っています。ライブラリ間の循環依存関係は、存在するとしてもめったにありませんが、再検査する特定のライブラリを繰り返すことで、このモデルで使用することができます。

于 2012-04-07T23:19:03.330 に答える