1

私はこのファイルを持っています:

//Q2a.h
#ifndef Q2A_H
#define Q2A_H

inline int MyFactorial(int a)
{
if (a < 2)
    return 1;
return a*MyFactorial(a-1);
}

int NumPermutations(int b);
#endif

//Q2a.cpp
#include "Q2a.h"

int NumPermutations(int b)
{
    return MyFactorial(b);
}

and file with the main- Q2b.cpp

再帰関数がある場合、コンパイラは通常、インライン宣言を無視することに気付きました。しかし、私の質問は、インライン宣言を削除すると、次のことができる理由です。

g++ -Wall -g -c Q2a.cpp -o Q2a.o
g++ -Wall -g -c Q2b.cpp -o Q2b.o

それらは問題ありませんが、リンケージ段階では:

g++ -Wall -g -c Q2a.o Q2b.o -o Q2

エラーが表示されます: `MyFactorial(int) の複数の定義

4

3 に答える 3

1

関数を宣言すると、関数inlineの定義に適用される規則が変更されます。

inline関数は、プログラム内で一度だけ定義する必要があります。対照的に、inline関数は複数の翻訳単位で定義できますが、定義は同一である必要があり、関数はそれが使用されるすべての翻訳で定義されている必要があります。

を削除するinlineと、以前の「1 つの定義ルール」からの除外が削除されます。

于 2010-09-05T21:28:46.793 に答える
1

あなたが のとき#include "Q2a.h"、あなたは本質的にコンテンツのテキスト置換を行っているため、 Q2a.cpp と Q2b.cpp の両方が という関数を定義することになりますMyFactorial()。を使用するかinline、ソース ファイルの 1 つで関数を定義する必要があります。

inlineを使用しても、再帰関数ではあまり役に立たないことに注意してください。

于 2010-09-05T19:32:58.777 に答える
1

関数を as として宣言する GCC では、関数inlineをインライン化するようにコンパイラに指示するだけです。ただし、コンパイラは、別のコンパイル ユニットから呼び出すことができる非インライン関数を生成します。

あなたの場合、これらの関数には名前の衝突がありました。簡単に言えば、インラインは静的を意味するものではありません。

あなたがしたいことは、関数を次のように宣言することですstatic inline

これにより、関数をインライン化する必要があることがコンパイルに伝えられます。コンパイラーがインライン化することを決定した場合、同じ関数の静的バージョンは必要ありません。コンパイラが関数をインライン化できない場合、関数が静的であることを確認します。たとえば、関数の名前は C ファイルに対してローカルであり、プログラムのリンク中に名前の衝突は発生しません。

ヒント:

コンパイラは異なる動作をします。将来、別のプラットフォームでコードをコンパイルする場合は、必ずマクロで定義を非表示にしてください。

たとえばstatic inline、GCC と Visual Studio には使用する必要があり_inline、TI Code Composer DSP/組み込み ARM コンパイラにはシンプルなものを使用する必要があります。後者のコンパイラは、非標準で static _inline も理解しないため、プレーンなインラインを理解できません。

于 2010-09-05T20:11:04.423 に答える