web-dev-qa-db-ja.com

`sin`への未定義の参照

私は次のコードを持っています(この質問の最低限の基本に取り払われています):

#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を呼び出すさまざまなテストプログラムを作成しましたが、これらは完全に機能します。私はここで明らかに間違ったことをしなければなりません-しかし、それは何ですか?

90
robintw

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

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

コメント で、 linuxD は次を要求します:

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

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

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

標準Cライブラリ

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

標準C数学ライブラリ

このライブラリは、Volume 1で定義されているBase System数学ルーチンをサポートしています。ccオプション-lmは、このライブラリの検索に使用されます。

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

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

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

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

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

110
Edwin Buck

とにかく-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

問題なくリンクするだけ

そのため、後でライブラリを指定する必要があります。

61
Anyeos

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

$ gcc -Wall foo.c -o foo -lm 
38
Paul R

私は同じ問題を抱えていましたが、最後にライブラリをリストした後に消えました:gcc prog.c -lm

10
blackappy