0

私はmath.hで定義されたpow関数を使用しなければならないacプロジェクトをプログラミングしています。そして、私がプロジェクトを作成しようとしたとき、gccは次のリンクエラーを出しました:`pow'への未定義の参照。

リンク命令に-lmオプションを追加する必要があることは知っていますが、それでも私を困惑させるいくつかの質問があります。

Q1:2つの定数をpow関数に渡すと、-lmがなくてもリンクは成功します。なんで?

Q2:-lmがリンク命令の最後または最初にあると、異なる結果になります。gcc -lm $(OBJS)-o exbinは間違っていますが、gcc $(OBJS)-oexbin-lmは正しいです。なんで?

私はubuntu11.10とgcc4.4.4を使用しています。

ありがとう!私のプールの英語を許してください。

4

2 に答える 2

1

コンパイラーpow(3, 4)は、コンパイル時に結果を計算することによってプログラムを最適化します。そのため、リンク時および実行時にライブラリーは必要ありません。

リンカは、ライブラリが必要であることがわかっていない限り、ライブラリからコンテンツを追加しません。静的ライブラリでは、それは厳密に真実でした。共有ライブラリを使用すると、一部のバージョンのコンパイラは、ライブラリのスキャン時に必要でなかった場合でも、読み取られたすべての共有ライブラリのすべてのシンボルを記録します。最近のバージョンでは、スキャン時にシンボルの少なくとも1つが必要な場合にのみ、共有ライブラリを取り込みます。ライブラリが最初に来るとき、必要なシンボルはmain()(そのmain()ため、ホストされた環境の開始点として指定されている)だけです。したがって、必要なシンボルが含まれていないため、数学ライブラリは無視されました。

于 2012-04-10T03:54:02.627 に答える
0

質問1には答えられませんが(奇妙に思えます)、質問2に関しては、使用gcc -lm $(OBJS) -o exbin順にリンクする必要があるため、うまくいきません。これは例によって最もよく説明されます:

/* File func_a.h */
/* Declare func_a */
void func_a();

/* File func_a.c */
#include "func_a.h"
void func_a()
{
    /* do stuff */
}

/* File func_b.c */
#include "func_a.h"
void func_b()
{
    /* Call func_a */
    func_a();
}

実行可能ファイルに適切にリンクするfunc_aには、を使用するため、func_bそれらをリンクする必要があります。つまり、ライブラリ関数を最後にリンクする必要があります。gcc func_b func_a -o execfunc_bfunc_a

于 2012-04-10T03:49:01.400 に答える