9

ここにサンプルファイルがあります:

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

int main(){
  printf("%f\n", log(10));
}

私がそれをコンパイルするとgcc sample.c -o a、うまく動作します。で実行でき、期待どおり./aの出力が生成2.302585されます。

それでも、私のファイルが次のようになっている場合:

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

int main(){
  double a = 10;
  printf("%f\n", log(a));
}

ではコンパイルされませんgcc sample.c -o a。代わりに、gcc sample.c -o a -lm「数学をリンクする」ように明らかに指示できるように使用する必要があります...それは私が実際には従わないところです.最初の例で数学をリンクする必要がないのはなぜですか? そして、「数学をリンクする」必要があるとは、正確にはどういう意味ですか? C コンパイラを使用するのは久しぶりなので、質問が下手だったらすみません。

4

3 に答える 3

6

数学ライブラリ関数は呼び出されない場合があります。GCC ドキュメントによると、一部のインライン関数が定義されており、特定の状況で代わりに呼び出される場合があります。

... GNU C ライブラリは、頻繁に使用される多くの数学関数の最適化を提供します。GNU CC が使用され、ユーザーがオプティマイザーをアクティブにすると、いくつかの新しいインライン関数とマクロが定義されます。これらの新しい関数とマクロは、ライブラリ関数と同じ名前であるため、後者の代わりに使用されます。インライン関数の場合、コンパイラはそれらを使用することが合理的かどうかを決定します。この決定は通常正しいものです。

これは、ライブラリ関数の呼び出しが必要ないことを意味し、生成されたコードの速度を大幅に向上させることができます。欠点は、コード サイズが大きくなることであり、その増加は常に無視できるとは限りません。

于 2013-10-21T05:59:04.313 に答える
6

log()逆アセンブルを確認すると、最初のケースではコンパイラが out の呼び出しを完全に最適化していることがわかります(したがって、リンクするものは何もありません) が、2 番目のケースではそうではありません。この特定のケースでは、glibc は以下を定義します。

# define M_LN10     2.30258509299404568402

math.hたとえば、任意の標準ライブラリ関数をマクロとして実装できるため、関数呼び出しなしでこれらのいくつかを計算できます。

于 2013-10-21T05:27:49.600 に答える