2016-05-17 29 views
2

は、いくつかの良い魂は、ケースには、私は(そう
gcc main.c -o main -lmなど)-lm gccのオプションを使用する必要がない理由私が理解するのに役立つだろう(1)とケース(2)には持っていないのですか?C数学SQRTとgcc -lmオプション

ケース(1)

#include <math.h> 
int main() { 
    float x = 4; 
    sqrt(x); 
    return 0; 
} 

ケース(2)

#include <math.h> 
int main() { 
    sqrt(4); 
    return 0; 
} 

私はgccで、Ubuntuの16.04を使用しています。 なぜ私は-lmを使用すべきか分かりますが、なぜケース(2)がそれなしで動作するのかわかりません。

+1

原因 'sqrt(4)'が2であることをコンパイラが知っているからです。最初のケースでは、 'gcc -O3 main.c -o main'を試してみてください。 – user3386109

+0

ありがとう、兄さん! –

答えて

1

いくつかの機能を見てみましょう。 gcc -O3 -c so.cでコンパイル

#include <math.h> 

double func(double num) { 
    return sqrt(num); 
} 

objdump -d so.oで分解:ここでは最初のものだ

0000000000000000 <func>: 
    0: f2 0f 51 c8    sqrtsd %xmm0,%xmm1 
    4: 66 0f 2e c9    ucomisd %xmm1,%xmm1 
    8: 7a 05     jp  f <func+0xf> 
    a: 66 0f 28 c1    movapd %xmm1,%xmm0 
    e: c3      retq 
    f: 48 83 ec 08    sub $0x8,%rsp 
    13: e8 00 00 00 00   callq 18 <func+0x18> 
    18: 48 83 c4 08    add $0x8,%rsp 
    1c: c3      retq 

をだから我々は、FPUのレジスタ操作の束、およびコールを持っています。その呼び出しが何を呼び出すかを見てみましょう。 nm so.oを実行します。

0000000000000000 T func 
       U sqrt 

だから我々は(T) "FUNC" と呼ばれる機能、およびインポート(Usqrtと呼ばれるシンボルを定義しています。最終的なプログラムは、sqrtが実際に定義されている通り、-lmとリンクする必要があります。いいえFPUのレジスタ操作を

0000000000000000 <func>: 
    0: f2 0f 10 05 00 00 00 movsd 0x0(%rip),%xmm0  # 8 <func+0x8> 
    7: 00 
    8: c3      retq 

を:gcc -O3 -c so.cでコンパイルしないとobjdump -d so.oで分解し、再び

#include <math.h> 

double func() { 
    return sqrt(4); 
} 

今度は、第2の機能を試してみましょう。関数呼び出しはありません。 nm so.oで確認しましょう:

0000000000000000 T func 
0000000000000000 r .LC0 

イエップ。記号のインポートはありません。

あなたが#include <math.h>を省略した場合は、ここで何が起こっているかのヒントを得る:

$ gcc -O3 -g -c so.c 
so.c: In function ‘func’: 
so.c:2:10: warning: incompatible implicit declaration of built-in function ‘sqrt’ 
    return sqrt(4); 
     ^

sqrtは、組み込み関数です。コンパイラはそれをいくつかの不透明な構造として扱いません。それはそれが何を理解します。後者の場合、コンパイラは実行時に関数を呼び出す必要はないことを理解しています。それはコンパイル中の答えが何であるかを知っています。それは返信用レジスタに回答を入れ、それを1日と呼びます。実行時間にsqrtの呼び出しが含まれていないため、-lmとリンクする必要はありません。

+0

男、あなたは素晴らしいです! :) ありがとうございました! –

関連する問題