29

これは私の問題を概説する最小限の例です

test.c:

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

main ()
{
   fmod ( 3, 2 );
}

そして、ここに私がコンパイルするために発行しているコマンドがありますtest.c

gcc -lm test.c -o test

上記のコマンドを発行したときに得られる出力は次のとおりです

/tmp/ccQmRk99.o: In function `main':
test.c:(.text+0x3e): undefined reference to `fmod'
collect2: ld returned 1 exit status

代わりに を使用すると、同じ出力が得られますcc。次のバージョンのgccを使用しています

gcc-4.6.real (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1

私のプログラムがコンパイルされない理由はありますか?

4

2 に答える 2

62

ld問題は、gcc ではなくリンカ (したがって、終了ステータス メッセージ) から発生しています。一般に ld では、オブジェクトとライブラリを の順序user supplierで指定する必要があります。ここuserで、 はライブラリ関数を使用するsupplierオブジェクトであり、 はそれを提供するオブジェクトです。

あなたtest.cがオブジェクトにコンパイルされると、コンパイラは fmod が未定義の参照であることを示します

$ gcc -c test.c
$ nm test.o
                 U fmod
0000000000000000 T main

(nm は、オブジェクト ファイルによって参照されるすべての関数を一覧表示します)

リンカーは、未定義の参照を定義済みの参照に変更し、参照を検索して、それらが他のファイルで提供されているかどうかを確認します。

$ gcc -lm test.o
$ nm a.out
0000000000600e30 d _DYNAMIC
0000000000600fe8 d _GLOBAL_OFFSET_TABLE_
00000000004006a8 R _IO_stdin_used
                 w _Jv_RegisterClasses
0000000000600e10 d __CTOR_END__
...
0000000000601018 D __dso_handle
                 w __gmon_start__
...
                 U __libc_start_main@@GLIBC_2.2.5
0000000000601020 A _edata
0000000000601030 A _end
0000000000400698 T _fini
0000000000400448 T _init
0000000000400490 T _start
00000000004004bc t call_gmon_start
0000000000601020 b completed.7382
0000000000601010 W data_start
0000000000601028 b dtor_idx.7384
                 U fmod@@GLIBC_2.2.5
0000000000400550 t frame_dummy
0000000000400574 T main

これらのほとんどは、環境をセットアップするために main の前後に実行される libc 関数を参照しています。fmod が共有ライブラリ システムによって解決される glibc を指していることがわかります。

私のシステムは、デフォルトで共有ライブラリを使用するように設定されています。代わりに静的リンクを強制すると、表示される順序の依存関係が得られます

$ gcc -static -lm test.o
test.o: In function `main':
test.c:(.text+0x40): undefined reference to `fmod'
collect2: ld returned 1 exit status

-lmリンカー コマンドの の後ろ に置くと、test.o正常にリンクできます。シンボル fmod を確認すると、実際のアドレスに解決されるはずです。

$ gcc -static test.o -lm
$ nm a.out | grep fmod
0000000000400480 T __fmod
0000000000402b80 T __ieee754_fmod
0000000000400480 W fmod
于 2012-07-05T00:24:00.530 に答える