「pow」および「floor」への未定義の参照


124

Cで単純なフィボナッチ計算機を作成しようとしていますが、コンパイルするgccと、pow関数とfloor関数が不足していることがわかります。どうしましたか?

コード:

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

int fibo(int n);

int main() {
        printf("Fib(4) = %d", fibo(4));
        return 0;
}

int fibo(int n) {
        double phi = 1.61803399;

        return (int)(floor((float)(pow(phi, n) / sqrt(5)) + .5f));
}

出力:

gab@testvm:~/work/c/fibo$ gcc fib.c -o fibo
/tmp/ccNSjm4q.o: In function `fibo':
fib.c:(.text+0x4a): undefined reference to `pow'
fib.c:(.text+0x68): undefined reference to `floor'
collect2: ld returned 1 exit status

浮動小数点の精度は無限ではないので、これはそれほど大きくない値に対して誤った答えを出しますn
vonbrand


さらに簡単な解決策があるようですが、代わりにg ++を使用してください。g ++ fib.c -o fibo
OrenIshShalom

回答:


242

次の-lmように、リンクフラグを指定してコンパイルする必要があります。

gcc fib.c -lm -o fibo

これは、glibに数学ライブラリに対してコードをリンクするように指示します。リンクするオブジェクトの後に必ずフラグを付けてください。


7
-lの後に付ける文字の作り方を説明していただけませんか。
Gabriele Cirulli、2011

48
/ libまたは/ usr / libを調べます。ライブラリはすべて名前が付けられているlib<name>.aか、lib<name>.so-の後に置く「<name>」です-l。この場合、数学ライブラリはと名付けられているlibm.soので、これをと呼びます-lm
AMS

3
ありがとう!私は過去30分間グーグルで操作してきましたが、これはオブジェクトの後にライブラリをリンクすると言った最初のリファレンスです
Dave Baghdanov

LD_PRELOADを使用して、ldランタイムリンカーにlibm.soをプロセスのメモリマップとシンボルテーブルに含めるように指示することもできます。これにより、これらのシンボルが読み込まれ、すべてが期待どおりに機能します
debuti

答えてくれてありがとう。しかし、数行のコードの場合、コンパイル中に-lmを含めなくても問題ない理由を誰かに教えてもらえますか?
MItrajyoti Kusari

24

pow()およびfloor()は数学ライブラリの一部であるため、リンクオプションに-lmを追加します。

gcc fib.c -o fibo -lm

9

後でこれを読む人のために、フレッドが言ったようにリンクする必要があります:

gcc fib.c -lm -o fibo

リンクする必要のあるライブラリを見つける1つの良い方法は、manページが存在するかどうかを確認することです。たとえば、man powman floorの両方を教えてくれます。

とリンクし-lmます。

Cプログラミングで数学ライブラリをリンクするための説明-Cでのリンク


8

ファジーが提供する答えに関して:

実際には少し違うことをしなければなりませんでした。

プロジェクト->プロパティ-> C / C ++ビルド->設定-> GCC Cリンカー->ライブラリ

小さな緑色の追加アイコンをクリックし、mと入力して[OK]をクリックします。このウィンドウはライブラリであるため、すべてのウィンドウに-lが自動的に適用されます。


6

Eclipse-IDEで-lmを追加する場所を見つけるのは本当に恐ろしいので、少し時間がかかりました。

他の誰かがEdlipseも使用している場合、コマンドを追加する方法は次のとおりです。

プロジェクト->プロパティ-> C / C ++ビルド->設定-> GCC Cリンカー->その他->リンカーフラグ:このフィールドにコマンド-lmを追加します


0

上記の答えはすべて不完全です。ここでの問題ldは、コンパイラーではなくリンカーにありますcollect2: ld returned 1 exit statusfib.ctoオブジェクトをコンパイルする場合:

$ gcc -c fib.c
$ nm fib.o
0000000000000028 T fibo
                 U floor
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
                 U pow
                 U printf

where nmは、オブジェクトファイルのシンボルをリストします。あなたは、これはエラーなしでコンパイルされたことがわかります、しかしpowfloorprintf私は実行可能ファイルにこれをリンクしようとする場合の機能は現在、未定義の参照を持っています:

$ gcc fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

私はあなたが得る同様の出力を得ています。それを解決するために、私はどこへの参照を探す場所をリンカーに伝える必要がありpow、そしてfloor、この目的のために、私は、リンカの使用する-lとフラグmから来ているlibm.soライブラリを。

$ gcc fib.o -lm
$ nm a.out
0000000000201010 B __bss_start
0000000000201010 b completed.7697
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
0000000000201000 W data_start
0000000000000620 t deregister_tm_clones
00000000000006b0 t __do_global_dtors_aux
0000000000200da0 t 
__do_global_dtors_aux_fini_array_entry
0000000000201008 D __dso_handle
0000000000200da8 d _DYNAMIC
0000000000201010 D _edata
0000000000201018 B _end
0000000000000722 T fibo
0000000000000804 T _fini
                 U floor@@GLIBC_2.2.5
00000000000006f0 t frame_dummy
0000000000200d98 t __frame_dummy_init_array_entry
00000000000009a4 r __FRAME_END__
0000000000200fa8 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
000000000000083c r __GNU_EH_FRAME_HDR
0000000000000588 T _init
0000000000200da0 t __init_array_end
0000000000200d98 t __init_array_start
0000000000000810 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000800 T __libc_csu_fini
0000000000000790 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
00000000000006fa T main
                 U pow@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
0000000000000660 t register_tm_clones
00000000000005f0 T _start
0000000000201010 D __TMC_END__

これで、関数powfloorがリンクされていることがわかりGLIBC_2.2.5ます。

パラメータの順序も重要です。システムがデフォルトで共有ライブラリを使用するように構成されていない限り、私のシステムはそうではないため、次のコマンドを発行すると、

$ gcc -lm fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

-lmオブジェクトファイルの前のフラグに注意してください。したがって、結論として、-lm他のすべてのフラグとパラメータの後にフラグを追加してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.