1

私はちょうどC++を学んでいます。g++ バージョン 3.2.3、「g++ hworld.cpp」でコンパイル:

double sqrt(double);
int main(){
    double x = sqrt(1515.15);
    return 0;
}

これは正常にコンパイルされますが、sqrt を "sqrtfoo" に置き換えると、コンパイラは sqrtfoo を関数として使用できないと言うでしょう。cmath を含める必要があると思いましたが、そうではないでしょうか。インクルードする前に、私のプログラムが何にアクセスできるかを誰か説明してもらえますか? 比較のために言うと、gcc では、「'sqrt' への未定義の参照」と言って、これを行うことができません。ありがとうございました。

4

3 に答える 3

3

コードには最初の行に既にcmathプロトタイプがあるため、含める必要はありません。sqrt

于 2012-09-17T04:21:23.213 に答える
2

既存の回答が説明しdouble sort(double)ているように、関数が存在することをコンパイラに知らせるプロトタイプを提供します。

しかし、これは GCC では機能しないとも言いました。C または C++ プログラムをビルドすると、ソース コードはオブジェクト形式にコンパイルされます。次に、オブジェクト ファイルがリンクされて、実行可能ファイルが形成されます。

これを実際に確認するには、試してください

gcc -c hello.c

これは、ソースファイル hello.c をコンパイル (-c) するように GCC に指示します。hello.c が存在し、エラーがないと仮定すると、現在のディレクトリに hello.o が見つかります。今すぐ試してください

gcc -o hello hello.o

これにより、GCC は hello.o を適切なシステム ライブラリにリンクし、"hello" という出力ファイルを生成するように指示されます。hello.c が数学関数を使用する場合は、数学ライブラリにもリンクする必要があります。

gcc -o hello hello.o -lm

「-l」は、gcc に追加のライブラリ (デフォルトの「libc」C ライブラリ以外) を含めるように指示するために使用されます。"m" は "libm" を指し、これは を含む数学ライブラリですsqrt。プログラムが 1 つのソース ファイルのみを使用する場合、暗黙的に GCC にコンパイルとリンクを 1 つのコマンドで要求するのが一般的です。

gcc -o hello hello.c -lm

今あなたの質問に。数学ライブラリへのリンクを要求していないため、GCC は上記のコードをコンパイルしません。しかし、g++ はそれで問題ありません。スタック オーバーフローに既に非常によく似た質問があります。その受け入れられた答えによると、

C++ ランタイム libstdc++ は libm を必要とするため、C++ プログラムを GCC (g++) でコンパイルすると、自動的に libm がリンクされます。

「libstdc++」は C++ 言語ランタイム ライブラリであるため、デフォルトで g++ に含まれています。また、libm に依存するため、リンカーは最終的なバイナリ プログラムを生成する際に自動的に libm をロードします。

于 2012-09-17T05:11:07.040 に答える
1

ヘッダー ファイルは宣言 (署名) のみを保持し、最初の行に 1 つ含めました (prototype: double sqrt(double))。

この関数がどこかに定義されていると述べたので、コンパイラはそれをうまくコンパイルします。コンパイル後に発生するステップは、その関数定義を実際に探す責任があります。それは と呼ばれlinking、その段階でリンカはそれらの定義を検索します。sqrtfoo何も見つからない場合は、標準sqrtライブラリで見つかります(詳細はわかりません)。

于 2012-09-17T04:25:16.597 に答える