2012-01-22 17 views
2

私の問題はちょっと面白くて、私のUbuntuボックスで何が起こっているのかを知りたいと思います。リンクエラー - gcc -lm

私は、次のコード無用コンパイルとgcc -lm -o useless useless.cとリンク:これまでのところは良い

/*File useless.c*/ 
#include <stdio.h> 
#include <math.h> 
int main() 
{ 
    int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * 440 * ((float) 1/44100))); 
    return(0); 
} 

を。

/*File useless.c*/ 
#include <stdio.h> 
#include <math.h> 
int main() 
{ 
    int freq = 440; 
    int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * freq * ((float) 1/44100))); 
    return(0); 
} 

と私は同じコマンドライン、gccの応答使用してコンパイルしよう:しかし、私はこれを変更するとき

/tmp/cctM0k56.o: In function `main': 
ao_example3.c:(.text+0x29): undefined reference to `sin' 
collect2: ld returned 1 exit status 

して停止します。何が起こっている?なぜ私はそのようにコンパイルできないのですか?

私もsudo ldconfig -vを試しましたが、成功しませんでした。

ありがとうございました!

ルーカス。

+0

'int main()'は 'int main(void)'でなければなりません。 'return'ステートメントのかっこは不要です。 'return 0;'と書くだけです。 –

答えて

11

ここでは2つの異なることが起こっています。

最初の例では、コンパイラはsinの呼び出しを生成しません。引数が定数式であることがわかるので、sin(...)呼び出しを式の結果に置き換え、数学ライブラリは不要です。 -lmがないとうまく動作しません。

を(あなたが

gcc -S useless.c 

でコンパイルした場合と取る;(コンパイラは最適化のこの種を行いますとき、それは必ずしも明確ではないとするとき、それはしませんが、あなたはそれを当てにはなりません。) 。第二の例について

に)、あなたはsinへの呼び出しがありませんことを確認することができ、useless.sで生成されたアセンブリ言語のリストを見て、あなたは-lmオプションが必要です - それは、コマンドラインの最後にする必要があります、または少なくともそれを必要とするファイル(useless.c)の後に:

gcc -o useless useless.c -lm 

または

gcc useless.c -lm -o useless 

リンカは(useless.oで呼ばsin、)それぞれについて、未解決のシンボルを追跡し、それが彼らの定義を見ていると、それらを解決する、順番にファイルを処理します。最初に-lmを入力すると、数学ライブラリを処理するときに未解決の記号はありません。 sinへのコールがuseless.oにあるときには、それは遅すぎます。

+1

私は同じことをポストしようとしていましたが、なぜ成功したのか理解できませんでした( 'sin()'も使われています)。 – hmjd

+0

@hmjd:ああ、私はあまりにも速くそれを読んでいます。私の更新された答えを見てください。 –

+0

+1、非常に便利です。 – hmjd

関連する問題