118

私は次のコードを持っています(この質問の基本的な部分にまで絞り込みました):

#include<stdio.h>
#include<math.h>

double f1(double x)
{
    double res = sin(x);
    return 0;
}

/* The main function */
int main(void)
{
    return 0;
}

でコンパイルするとgcc test.c、次のエラーが発生しますが、その理由を理解できません。

/tmp/ccOF5bis.o: In function `f1':
test2.c:(.text+0x13): undefined reference to `sin'
collect2: ld returned 1 exit status

sinただし、関数内から呼び出すさまざまなテストプログラムを作成しましたがmain、それらは完全に機能します。私はここで明らかに間違ったことをしているに違いありませんが、それは何ですか?

4

4 に答える 4

143

正しいmath.hヘッダーファイルへの参照を使用してコードをコンパイルしましたが、それをリンクしようとしたときに、数学ライブラリをインクルードするオプションを忘れました。その結果、.oオブジェクトファイルをコンパイルすることはできますが、実行可能ファイルをビルドすることはできません。

-lmPaulがすでに述べたように、実行可能ファイルを生成しようとしているステップで数学ライブラリにリンクするために「」を追加します。

コメントで、linuxDは次のように質問します。

なぜ、sin()で、明示的にオプション<math.h>が必要なのですか。-lmしかし、ではありませんprintf()<stdio.h>

これらの機能は両方とも「SingleUNIXSpecification」の一部として実装されているためです。この標準のこの歴史は興味深いものであり、多くの名前で知られています(IEEE Std 1003.1、X / Open Portability Guide、POSIX、Spec1170)。

この標準は、特に「標準Cライブラリ」ルーチンを「標準C数学ライブラリ」ルーチン(277ページ)から分離します。関連する一節を以下にコピーします。

標準Cライブラリ

cc標準Cライブラリは、外部参照を解決するために自動的に検索さ れます。このライブラリは、数学ルーチンを除いて、第1巻で定義されているベースシステムのすべてのインターフェイスをサポートします。

標準C数学ライブラリ

このライブラリは、第1巻で定義されているように、基本システムの数学ルーチンをサポートしています。このccオプション -lmは、このライブラリを検索するために使用されます。

この分離の背後にある理由は、いくつかの要因の影響を受けました。

  1. UNIX戦争は、元のAT&TUNIX製品からの相違を増大させました。
  2. UNIXプラットフォームの数により、オペレーティングシステム用のソフトウェアの開発が困難になりました。
  3. 1988 POSIXと呼ばれる、ソフトウェア開発者の最小公分母を定義する試みが開始されました。
  4. ソフトウェア開発者は、より多くのプラットフォームに到達するために、「POSIX準拠システム」でソフトウェアを提供するようにPOSIX標準に対してプログラムしました。
  5. UNIXのお客様は、ソフトウェアを実行するために「POSIX準拠」のUNIXシステムを要求しました。

別のライブラリを配置するという決定につながった圧力には-lm、おそらく次のものが含まれますが、これらに限定されません。

  1. 多くのアプリケーションは数学ライブラリに埋め込まれた関数を使用しないため、libcのサイズを抑えるのに良い方法のようです。
  2. これは、数学ライブラリの実装に柔軟性を提供します。一部の数学ライブラリは、より大きな埋め込みルックアップテーブルに依存し、他の数学ライブラリは、より小さなルックアップテーブル(コンピューティングソリューション)に依存する場合があります。
  3. 真にサイズに制約のあるアプリケーションの場合、非標準的な方法で数学ライブラリを再実装できます(たとえば、引き出してsin()カスタムビルドのライブラリに入れるなど)。

いずれにせよ、C言語の一部として自動的に含まれないことが標準の一部になっているため、を追加する必要があります-lm

于 2011-02-15T15:13:31.817 に答える
79

とにかく-lmを追加すると問題が発生します

gcc -Wall -lm mtest.c -o mtest.o
mtest.c: In function 'f1':
mtest.c:6:12: warning: unused variable 'res' [-Wunused-variable]
/tmp/cc925Nmf.o: In function `f1':
mtest.c:(.text+0x19): undefined reference to `sin'
collect2: ld returned 1 exit status

最近、最初に-lmを指定すると機能しないことがわかりました。順序は重要です:

gcc mtest.c -o mtest.o -lm

問題なくリンクするだけ

したがって、後でライブラリを指定する必要があります。

于 2012-08-28T18:08:14.843 に答える
42

数学ライブラリlibmとリンクする必要があります。

$ gcc -Wall foo.c -o foo -lm 
于 2011-02-15T15:12:10.477 に答える
11

同じ問題が発生しましたが、最後にライブラリをリストした後に解消されました:gcc prog.c -lm

于 2012-01-13T08:19:45.440 に答える