G ++を使用してプロジェクトをリンクするときに、宣言されているが実装されていない関数がある場合、それらを呼び出そうとしない限り、エラーは発生しないことに気付きました。
Q1:関数が宣言されているが実装されていない場合、エラー(または少なくとも警告)を有効にすることは可能ですか?
Q2:なぜこの動作なのですか?
(注: gccが使用するリンカーの場合は、パッケージからを使用していG++ 4.7.0
ます)ld 2.22
mingw
A2:外部リンケージを持つ非インライン関数などのエンティティは、プログラム内で0または1つの定義を持つことができます。実際に使用される場合(厳密にはodr-used )、たとえば呼び出される場合は、1つの定義のみが必要です。g ++は、使用されていない未定義の関数に対してエラーを発行した場合、エラーになります。
A1:したがって、これを強制的にエラーにすることは(準拠した方法で)できません。
単体テストを作成します。関数が存在しない場合、それをテストするコードは失敗します。
関数が宣言されているだけの場合、(コンパイル時に)単一のコンパイル単位でエラーを取得する方法はありません。その関数は別のコンパイル単位で定義できるためです。
(コンパイラでプラグインが有効になっているLinuxシステムを想定して)GCCプラグイン、またはより良いMELT拡張(MELTはGCCを拡張するための高レベルのドメイン固有言語)を作成できます。これにより、たとえば、へのポインタの配列が作成されます。宣言されたすべての関数(したがって、関数が定義されていない場合、リンク時にエラーが発生します)。未定義であるが宣言されているすべての関数に対して警告するMELT拡張機能を作成することもできます。
また、プラグイン、別のオブジェクト、またはライブラリによって提供される必要がある場合など、関数を宣言するが定義しないのには十分な理由がある場合があります。
また、ヘッダーファイルは通常関数を宣言しますが、それらを定義しません。これらの機能は通常、リンク時にライブラリによって提供されます。
参照されていない未定義のメンバー関数を仮想化することにより、リンカーにエラーを生成させることができます。明らかに、これには他の影響があるので、これにはプリプロセッサを使用することをお勧めします。何かのようなもの:
#ifdef TEST_COMPLETE_INTERFACE
#define REQUIRE_DEF virtual
#else
#define REQUIRE_DEF
#endif
class myClass
{
public:
REQUIRE_DEF void someMethod();
};
TEST_COMPLETE_INTERFACE
すべてが定義された状態で構築されていることを定期的に確認できます。これは、静的メソッドまたはフリー関数では機能しません。
GCC固有の属性があります。
void f() __attribute__((error("not implemented")));
int main() {
f();
}
与える
error: call to 'f' declared with attribute error: not implemented
この属性は、クラスメソッドでも使用できます。少なくともGCC4.4以降でサポートされています。