2

どうやら、MSVC2005はローカルクラスのメンバー関数をインライン化できず、LNK2005につながります。

以下をコンパイルするときに、このLNK2005エラーに直面しています。

common.hコンテンツ:

inline void wait_what()
{
  struct wtf
  {
    void ffffuuu() {}

  } local;
}

foo.cppコンテンツ:

#include "common.h"

void foo()
{
  wait_what();
}

bar.cppコンテンツ:

#include "common.h"

void bar()
{
  wait_what();
}

LNK2005.cppコンテンツ:

// forward declarations
void foo();
void bar();

int main()
{
  foo();
  bar();

  return 0;
}

エラーメッセージは次のとおりです。

error LNK2005: "public void __thiscall `void__cdecl wait_what(void)'::`2'::wtf::ffffuuu(void)" (?ffffuuu@wtf?1??wait_what@@YAXXZ@QAEXXZ) already defined in bar.obj

ローカルクラスについて、ISOIEC14882-2003は次のように述べています。

9.8ローカルクラス宣言

クラスは関数定義内で定義できます。このようなクラスはローカルクラスと呼ばれます。ローカルクラスの名前は、それを囲むスコープに対してローカルです。ローカルクラスは、囲んでいるスコープのスコープ内にあり、囲んでいる関数と同じように、関数の外部の名前にアクセスできます。ローカルクラスの宣言では、型名、静的変数、外部変数と関数、および囲んでいるスコープの列挙子のみを使用できます。

囲み関数には、ローカルクラスのメンバーへの特別なアクセス権はありません。通常のアクセスルール(11節)に従います。ローカルクラスのメンバー関数は、定義されている場合は、クラス定義内で定義されるものとします。

私は何か見落としてますか?

私には、コンパイラのバグのように見えます。GCCとMSVC2008はそれをうまくコンパイルします。ただし、実際にコールをインライン化するのか、リンクフェーズ中に2つのシンボルの1つを破棄するだけなのか疑問に思います。興味深いことに、このローカルクラスメンバー関数への呼び出しさえないことに気付くでしょう。

MSVC2005の回避策があるかどうか疑問に思います。私はMSDNでこの典型的な問題を検索しようとしましたが、あまり成功しませんでした。コンパイラの既知のバグのリストを見つけることさえできませんでした。


添付ファイル:LNK2005.zip

4

2 に答える 2

3

これは Visual Studio 2005 のバグで、vs 2008 で修正されました。

于 2010-01-16T16:40:56.403 に答える
1

私にはバグのように見えます。多分それがVS2008で動作する理由です。(ちなみに、マイクロソフト、これは、Visual Studio で IDE/コンパイラの依存関係を壊す正当な理由です。)

回避策として、明示的に を追加するinlineか、インライン化しないでくださいwait_what

于 2010-01-16T16:40:32.350 に答える