私は次のコードを持っています(この質問の最低限の基本に取り払われています):
#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
を呼び出すさまざまなテストプログラムを作成しましたが、これらは完全に機能します。私はここで明らかに間違ったことをしなければなりません-しかし、それは何ですか?
正しいmath.hヘッダーファイルへの参照を使用してコードをコンパイルしましたが、リンクしようとしたときに、数学ライブラリを含めるオプションを忘れていました。その結果、.oオブジェクトファイルをコンパイルできますが、実行可能ファイルはビルドできません。
Paulが既に言及したように、実行可能ファイルを生成しようとしているステップで数学ライブラリとリンクするために「-lm
」を追加します。
<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
は、このライブラリの検索に使用されます。
この分離の背後にある理由は、いくつかの要因に影響されました。
-lm
を別のライブラリに配置するという決定につながった圧力は、おそらく含まれていますが、これに限定されません:
sin()
だけを引き出してカスタムビルドライブラリに配置するなど)。いずれにせよ、C言語の一部として自動的に含まれないように標準の一部になったため、-lm
を追加する必要があります。
とにかく-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
問題なくリンクするだけ
そのため、後でライブラリを指定する必要があります。
数学ライブラリlibmとリンクする必要があります。
$ gcc -Wall foo.c -o foo -lm
私は同じ問題を抱えていましたが、最後にライブラリをリストした後に消えました:gcc prog.c -lm