views:

1174

answers:

6

I've got a really odd error message that only occurs when I add the following line to my project:

std::list<CRect> myVar;

It's worth noting that it doesn't have to be a std::list, it can be std::vector or any other STL container I assume.

Here is the error message:

Error 1 error LNK2005: "public: __thiscall std::list

::list >(void)" (??0?$list@VCRect@@V?$allocator@VCRect@@@std@@@std@@QAE@XZ) already defined in SomeLowLevelLibrary.lib

The low level library that's referenced in the error message has no idea about the project I am building, it only has core low level functionality and doesn't deal with high level MFC GUIs.

I can get the linker error to go away if I change the line of code to:

std::list<CRect*> myVar;

But I don't want to hack it for the sake of it.

Also, it doesn't matter if I create the variable on the stack or the heap, I still get the same error.

Does anyone have any ideas whatsoever about this? I'm using Microsoft Visual Studio 2008 SP1 on Vista Enterprise.

Edit: The linker error above is for the std::list<> constructor, I also get an error for the destructor, _Nextnode and clear functions.

Edit: In other files in the project, std::vector won't link, in other files it might be std::list. I can't work out why some containers work, and some don't. MFC linkage is static across both libraries. In the low level library we have 1 class that inherits from std::list.

Edit: The low level library doesn't have any classes that inherit from CRect, but it does make use of STL.

A: 

This doesn't sound like the exact symptom, but to be sure you should check that your main project and all your included libraries use the same "Runtime Library" setting under "C++:Code Generation". Mixing these settings can create runtime library link errors. (What confuses me in your case is that you can make it go away by changing the code, but it's worth checking if you haven't already.)

jeffm
Yeah, it's not the runtime support because we use that all over the place with MFC.
Mark Ingram
A: 

Does SomeLowLevelLibrary.lib contain or use any classes named CRect? Does it use STL?

JaredPar
+2  A: 

You should be looking at the linker settings, but I can't immediately say which. It's normal for STL instantiations to be done in multiple files. The linker should pick one. They're all identical (assuming you do have consistent compiler settings).

MSalters
A: 

Is the file included in a header which might be compiled into two seperate code modules?

Dan Pieczynski
A: 

Another random possibility popped into my head today. Is it possible that your current DLL and low level library are referencing two different versions of MFC? Long shot.

JaredPar
+1  A: 

I recently stumbled across this error again in our project and decided to have a more thorough investigation compared to just patching it up with a hack like last time (swap std::list for CArray). It turns out that one of our low level libraries was inheriting from std::list, e.g.

class LIB_EXPORT CRectList : public std::list<CRect>
{
};

This is not just bad practice, but it also was the cause of the linker errors in the main application. I change CRectList to wrap std::list rather than inherit from it and the error went away.

Mark Ingram