1. ホーム
  2. c

[解決済み] sin` への未定義の参照 [重複].

2022-02-15 02:14:59

質問

私は以下のようなコードを持っています(この質問のために基本的な部分まで削ぎ落としています)。

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

double f1(double x)
{
    double res = sin(x);
    return 0;
}

/* The main function */
int main(void)
{
    return 0;
}

でコンパイルすると gcc test.c 以下のようなエラーが発生し、原因がわかりません。

/tmp/ccOF5bis.o: In function `f1':
test2.c:(.text+0x13): undefined reference to `sin'
collect2: ld returned 1 exit status

しかし、様々なテストプログラムを書いてきて、その中で sin の中から main という関数があり、これらは完全に動作します。何か明らかに間違ったことをしているに違いないのですが、どうなのでしょうか?

解決方法は?

正しい math.h ヘッダーファイルへの参照を持つコードをコンパイルしましたが、リンクしようとしたときに、 math ライブラリをインクルードするオプションを忘れてしまいました。 その結果、.oオブジェクトファイルはコンパイルできますが、実行ファイルをビルドすることができません。

Paulが既に述べているように、"を追加します。 -lm 実行ファイルを生成しようとするステップで、数学ライブラリとリンクするように "してください。

での コメント , リナックスD が尋ねます。

なぜかというと sin()<math.h> が必要なのでしょうか? -lm オプションを明示的に指定します;しかし に対してではなく printf()<stdio.h> ?

なぜなら、これらの機能はいずれも "シングルUNIX仕様" の一部として実装されているからです。 この規格の歴史は興味深く、多くの名前で知られています(IEEE Std 1003.1, X/Open Portability Guide, POSIX, Spec 1170)。

この規格は 標準Cライブラリ"ルーチンと標準C数学ライブラリ"ルーチンを明確に分離(277ページ) . 以下、該当箇所をコピーします。

<ブロッククオート

標準Cライブラリ

標準Cライブラリは、自動的に cc を使用して外部参照を解決します。このライブラリは 第1巻で定義された基本システムのインターフェイスは、以下のものを除きます。 数学ルーチン

標準C言語数学ライブラリ

本ライブラリは 第1巻で定義された基本システムの数学ルーチン。その cc オプション -lm は、このライブラリの検索に使用されます。

この分離の理由は、いくつかの要因に影響されています。

  1. その UNIXウォーズ は、オリジナルのAT&T UNIXの提供からますます乖離することになった。
  2. UNIXのプラットフォームの数は、オペレーティングシステム用のソフトウェアの開発を難しくしていた。
  3. ソフトウェア開発者の最小公倍数を定義する試みが開始された。 1988年POSIXと呼ばれる .
  4. POSIX規格に準拠してプログラミングされたソフトウェア開発者は、より多くのプラットフォームに対応するため、自社のソフトウェアを「POSIX準拠のシステム」上で提供するようになりました。
  5. UNIXの顧客は、ソフトウェアを実行するために、POSIX準拠のUNIXシステムを要求した。

という決断に至った背景には、様々な圧力があった。 -lm を別のライブラリで使用することもできますが、それだけにとどまりません。

  1. 多くのアプリケーションは、数学ライブラリに埋め込まれた関数を使用しないので、libc のサイズを抑えるには良い方法だと思われます。
  2. ある数学ライブラリはより大きな組み込みルックアップテーブルに依存し、他のライブラリはより小さなルックアップテーブル(コンピューティングソリューション)に依存することができるような、数学ライブラリの実装における柔軟性を提供します。
  3. 本当にサイズに制約のあるアプリケーションでは、非標準の方法で数学ライブラリを再実装することができます。 sin() を作成し、カスタムビルドライブラリに配置することができます。

いずれにせよ、C言語の一部として自動的に含まれないことが標準になったので、そのために -lm .