2009-03-30 8 views
1

MSVC++ 2005を使いこなして、同じクラスが何度か定義されていれば、最高の警告レベルであっても、プログラムはうまくリンクしています。私はそれが驚くべきことを見つけます、どうしてこれは間違いではありませんか?同じクラスのいくつかの定義

module_a.cpp:

#include <iostream> 
struct Foo { 
    const char * Bar() { return "MODULE_A"; } 
}; 
void TestA() { std::cout << "TestA: " << Foo().Bar() << std::endl; } 

module_b.cpp:

#include <iostream> 
struct Foo { 
    const char * Bar() { return "MODULE_B"; } 
}; 
void TestB() { std::cout << "TestB: " << Foo().Bar() << std::endl; } 

main.cppに:

void TestA(); 
void TestB(); 
int main() { 
    TestA(); 
    TestB(); 
} 

、出力は次のとおりです。

TestA: MODULE_A 
TestB: MODULE_A 

答えて

3

エラーです。コードはC++ One Definition Ruleを破ります。そうすれば、標準では未定義の動作が起こると言います。あなたが持っていたかのため

コードリンクは、:両方のモジュールで

struct Foo { 
    const char * Bar() { return "MODULE_B"; } 
}; 

はODRの違反がないだろう - 結局、これは基本的にヘッダを#includingが何をするかです。違反はあなたの定義が異なっているので(他のものは文字列 "MODULE_A"を含んでいます)、これを検出するためのリンカー(単にクラス/関数名を見ている方法)はありません。

0

コンパイラは、テスト#()関数での使用以外にオブジェクトが役に立たないと考えて、全体をインライン化します。そうすれば、どちらのクラスも存在することはリンカが決して分かりません!しかし、ただのアイデア。

どういうわけか、TestAとクラスFoo [#]の間のリンクは、コンパイル内で実行されます。リンカーがクラスFoo(多重定義)を探していた場合には競合が発生しますが、リンカーは単にそれを探しません!

デバッグモードで最適化を有効にしないでコンパイルするとリンクエラーが発生しますか?

+0

インラインではありません。それが正しいとすれば出力は正しいだろう。コンパイラはおそらく、1つの(ランダムに選択された)シンボルを破棄しています。ニールが指摘したように、もし彼らが両方とも同じであれば、それは完全に大丈夫でしょう。 –

関連する問題