views:

158

answers:

2

Apparently, MSVC2005 fails to inline local classes' member functions which leads to LNK2005.

I'm facing this LNK2005 error when compiling the following:

common.h content:

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

  } local;
}

foo.cpp content:

#include "common.h"

void foo()
{
  wait_what();
}

bar.cpp content:

#include "common.h"

void bar()
{
  wait_what();
}

LNK2005.cpp content:

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

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

  return 0;
}

The error message is:

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

About local classes, ISO IEC 14882-2003 says:

9.8 Local class declarations

A class can be defined within a function definition; such a class is called a local class. The name of a local class is local to its enclosing scope. The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function. Declarations in a local class can use only type names, static variables, extern variables and functions, and enumerators from the enclosing scope.

An enclosing function has no special access to members of the local class; it obeys the usual access rules (clause 11). Member functions of a local class shall be defined within their class definition, if they are defined at all.

Did I miss something?

To me, it looks like it is a compiler bug. GCC and MSVC2008 compile it just fine. However, I wonder whether they would really inline the call or just discard one of the two symbols during the link phase. As an interesting note, you can notice that there is even no call to this local class member function.

I wonder whether there is a workaround for MSVC2005. I tried to search MSDN for this typical problem without much success: I wasn't even capable of finding a list of known bugs for the compiler.


Attachment: LNK2005.zip

A: 

It looks like a bug to me. Maybe that's why it works in VS2008. (Incidentally, Microsoft, this is a good reason for breaking the IDE/compiler dependency in Visual Studio.)

As for a workaround, try explicitly adding inline, or not inlining wait_what.

mos
Adding inline doesn't work. And, well the real situation is a macro that injects a local structure and it breaks when it's used in an `inline` function
Gregory Pakosz
+2  A: 

it was a bug in visual studio 2005, it was fixed in vs 2008

Alon
Would you have a reference to a bug report? or at lest a pointer to where I could search for one?
Gregory Pakosz
Alon