LNK2005 function pointer array "already defined" in .obj - c++

Ok a little introduction into the issue: I'm working on a rendering engine(compiling in 32 bit mode) in C++/DirectX11 in Visual Studio 2012 running on Windows 7 - 64 bit OS and I have a strange link error that comes up in my Entity class (the Entity3D is like the basic actor of the scene).
All of my bounding volume classes inherit from a Shape3D class.Each Entity has a Shape3D* boundingVolume member in it, that is initialized to a specific shape type at initialization time.
When colliding between two Shape3D's I pass them trough a function - bool Intersect(Shape3D* a, Shape3D* b) the function then checks their types(Sphere/*Box*/Whatever) and the type represents a number which is the index of a function in an array of function pointers:
bool(*IntersectArray[4][4])(Shape3D* a, Shape3D* b) =
{
{
IntersectSphereSphere,
IntersectSphereBox,
IntersectSphereOrientedBox,
IntersectSphereFrustum,
},
{
IntersectBoxSphere,
IntersectBoxBox,
IntersectBoxOrientedBox,
IntersectBoxFrustum
},
{
IntersectOrientedBoxSphere,
IntersectOrientedBoxBox,
IntersectOrientedBoxOrientedBox,
IntersectOrientedBoxFrustum
},
{
IntersectFrustumSphere,
IntersectFrustumBox,
IntersectFrustumOrientedBox,
IntersectFrustumFrustum
}
};
So it's like a virtual dispatch. Ok so the InersectArray is the array of the functions(declared in Intersect.h) and that's what gives me the link error:
error LNK1169: one or more multiply defined symbols found
error LNK2005: "char (__cdecl*(* Engine::Collision::IntersectArray)[4])(class Engine::Collision::Shape3D *,class Engine::Collision::Shape3D *)" (?IntersectArray#Collision#Engine##3PAY03P6ADPAVShape3D#12#0#ZA) already defined in Entity3D.obj
File Intersect.obj
Intersect.h is only included in Entity3D.cpp, it's no included in Entity3D.h, nor in any of the headers that Entity3D.h includes.Entity3D.cpp only includes Entity3D.h and Intersect.h.I cleaned and rebuilt, error persists.Intersect(Shape3D a, Shape3D* b)* is called only in one method of Entity3D in the Entity3D.cpp file. There are no other compile errors or warnings currently in the project. What else could cause such an issue?

Fixed the issue, I just moved the definition of IntersectArray in the Intersect.cpp file, since for now that's the only place it's needed.

Related

Why "unresolved external symbol" in VS2010 (lnk2001) when symbol is defined in .lib? C++, boost, cpputest

I'm getting this error from the linker:
1>PACBalancesTest.obj : error LNK2001: unresolved external symbol "public: bool __thiscall PAC::BalChgKeyComparator::operator()(class PAC::BalChgKey const &,class PAC::BalChgKey const &)const " (??RBalChgKeyComparator#PAC##QBE_NABVBalChgKey#1#0#Z)
I must be missing something really obvious, because I've looked at the definition of the "missing" symbol repeatedly and can't see any problem.
The symbol's definition is in a .lib file. I see the following in the output from dumpbin /symbols on that .lib file:
2F0 00000000 SECTFD notype () External | ??RBalChgKeyComparator#PAC##QBE_NABVBalChgKey#1#0#Z (public: bool __thiscall PAC::BalChgKeyComparator::operator()(class PAC::BalChgKey const &,class PAC::BalChgKey const &)const )
And there are other symbols being resolved successfully from that .lib file! (In fact, from the same .obj.) [Update: I no longer think the preceding statement is true. This may be my first attempt to access any function not defined in a .h file.]
WHAT FOLLOWS IS NOT RELEVANT TO THE PROBLEM -- SO PLEASE DON'T SPEND TIME STUDYING IT!
Here's the declaration of the function (in PACBalances.h):
namespace PAC {
class BalChgKey {
public:
...
};
struct BalChgKeyComparator {
bool operator()(const BalChgKey& lhs, const BalChgKey& rhs) const;
};
typedef std::multimap<BalChgKey, long, BalChgKeyComparator> BalChgKeyLongMMap;
};
Note that I've tried changing 'struct' above to 'class', with no effect.
Here is the calling code (in a cpputest test file):
#include "CppUTest/TestHarness.h"
#include <utility>
#include <map>
#include "PACBalances.h"
using namespace PAC;
...
TEST_GROUP(PACBalanceCUMap)
{
BalChgKeyLongMMap empty;
BalChgKeyLongMMap onesy;
void setup()
{
// **Adding the following line caused this error to start to occur.**
onesy.insert(std::pair<BalChgKey, long>(BalChgKey(BOPCAT_FEE, PAYMTYPE_OVERDRAFT_FEE, 4321, 41100, 1, 17), 17));
}
void breakdown()
{
}
};
And here is the definition of the operator function itself:
bool PAC::BalChgKeyComparator::operator()(
const BalChgKey& thing1,
const BalChgKey& thing2
) const
{
if (thing1.m_balKey.m_balCat < thing2.m_balKey.m_balCat) return true;
else if (thing1.m_balKey.m_balCat > thing2.m_balKey.m_balCat) return false;
// Fall thru if balCats are equal
...
return false;
}
Please note that:
The comparator, and the typedef'd multimap, works beautifully in lots of code (not shown above).
The test file calls lots of other functions declared and defined in that .h file, but this is the first time I've tried calling a function defined in a separate .cpp file.
My question is not why does the 'onesy.insert' call requires the comparator function. I understand that. It just happens to be the first multimap operation that I've coded in the test set that actually uses the comparator.
I have various hunches, but I'm running out of them, so if someone who knows about this stuff can give me any leads I would be very grateful.
Norm
#panta rei: You provided the key in your comment. (Sorry, can't figure out how to type Greek letters here.)
The problem was basically that I didn't know how to tell Visual Studio what objects to link in. I had told my solution that AnalyticsUTest depended on AnalysticsUTested, but the linking step is performed by the project (AnalyticsUTest), not the solution, so I needed to tell the project to include this .lib file.
So I went to the project's properties sheet and created two new macros, one giving the folder where VS was putting my .lib file (ANALYTICSUTESTED_LIB_PATHS), the other giving the name of my .lib file (ANALYTICSUTESTED_LIB_DEPENDENCIES) -- both by analogy with the CPPUTEST_LIB* macros.
And then I added $(ANALYTICSUTESTED_LIB_PATHS) to Linker > General > Additional Library Directories. And I added $(ANALYTICSUTESTED_LIB_DEPENDENCIES) to Linker > Input > Additional Dependencies.
And that fixed my problem! (I've spelled it out here in case another newbie like me comes along and needs it.)
Thank you, panta rei. How do I give you points for an answer provided via a comment?

Getting error LNK2019: unresolved external symbol in vS#)!) that compiled fine in VC 6.0

I am trying to compile a 14 year old C++ program with VS2010 C++ compiler (dont ask why :( ). I am getting the following error
Error 10 error LNK2019: unresolved external symbol "public: __thiscall CConfiguration::CConfiguration(void)" (??0CConfiguration##QAE#XZ) referenced in function
"public: __thiscall CWhoisService::CWhoisService(void)" (??0CWhoisService##QAE#XZ)
I have a cpp file CWhoisService.cpp with a header CWhoisService.h
CWhoisService.h:
class CWhoisService
{
public:
HRESULT Initialize(const char * szServiceName, REFCLSID pMetricsCLSID);
CWhoisService();
~CWhoisService();
HRESULT CheckService();
protected:
CConfiguration m_Configuration;
protected:
bool m_bStartedEvenLog;
bool m_bStartedConfiguration;
private:
//Don't want standard constructor to be called
};
CWhoisService.cpp
#include "ConfigurationLib.h"
#include "CWhoisService.h"
CWhoisService::CWhoisService():
m_bStartedEvenLog(false),
m_bStartedConfiguration(false)
{
}
HRESULT CWhoisService::Initialize(const char * szServiceName, REFCLSID pMetricsCLSID)
{
HRESULT hr = S_OK;
//Initialize the configuration library
hr = m_Configuration.Initialize(VERSION_COMPANY,VERSION_SYSTEM);
the ConfigurationLib.h file referenced in the cpp file and included before CWhoisService.h is as follows:
#ifndef _CONFIGURATION_MODULE
#define _CONFIGURATION_MODULE
class CConfigurationBase
{
public:
CConfigurationBase() : m_bInitialized(false) {};
virtual ~CConfigurationBase() {};
virtual HRESULT Initialize(LPCTSTR szCompanyName, LPCTSTR szSystemName, LPCTSTR szGlobalMachineName = NULL) = 0;
virtual bool IsInitialized() { return m_bInitialized;};
protected:
bool m_bInitialized; // True if the object has been initialized
};
class CConfiguration : public CConfigurationBase
{
public:
CConfiguration();
virtual ~CConfiguration();
// Initialized some values for the class. Must be called first!
virtual HRESULT Initialize(LPCTSTR szCompanyName, LPCTSTR szSystemName, LPCTSTR szGlobalMachineName = NULL);
protected:
// This is the function that actually goes about getting values from the registry
// The other Get functions all call this one
virtual HRESULT GetValue(HKEY hkeyBase, LPCTSTR szSectionName, LPCTSTR szValueName, CString * csValue, DWORD * pdwValue, DWORD dwType);
}; // CConfiguration
#endif // _CONFIGURATION_MODULE
everything was fine last time it compiled around 10 years ago. but now it does not seem to find the ConfigurationLib.h file. i made sure it as part of the project. if i removed it from the start of the cpp file I get the error: missing ';' before identifier 'm_Configuration' so ti obviously see it. yet it does not appear to be able to resolve the class.
Any assistance would be appreciated, i have spend last 3 days on this site and many others but no progress.
i have spend last 3 days on this site and many others but no progress
It is always good to understand the errors that are produced by the linker for Visual C++. Then next time you see such an error, it shouldn't take 3 days to figure out. I know the message looks garbled at first, but it really isn't if you know what to look for.
The trick is to choose the parts of the error that makes sense, and skip over the name-mangling (the gobbledy-gook that looks like the linker is swearing at you). Sometimes the name-mangling is useful, but for your error, it isn't important.
Let's go through the error:
unresolved external symbol "public: __thiscall CConfiguration::CConfiguration(void)"
The line above indicates the function implementation that cannot be found by the linker. The function is CConfiguration::CConfiguration(void). In other words, the 0-argument constructor for CConfiguration cannot be located by the linker.
Next part of the error message states:
referenced in function "public: __thiscall CWhoisService::CWhoisService(void)"
This is the function that is attempting to call the CConfiguration constructor. It is the CWhoisService::CWhoisService(void) constructor. You see it here:
class CWhoisService
{
//...
protected:
CConfiguration m_Configuration;
};
You have a member that is a CConfiguration (m_Configuration), so when you instantiate a CWhoIsService, you are also instantiating a CConfiguration object.
The bottom line is that the linker cannot find the implementation to the CConfiguration constructor that takes no arguments.
Either you
did not add the source module to your project that contains the implementation of the CConfiguration constructor to the project, or
The CConfiguration constructor is in a library and you didn't specify the library to link to in your project, or
You just plain old didn't code a CConfiguration constructor that has no arguments, or
some other unknown issue that causes the linker to miss the code that contains the implementation of the constructor.
My guess is more than likely item 1. above.
Also, this has nothing to do with header files. The header file allows a module to be compiled without error. It does not guarantee that the linker will link successfully.
For example, you can have a module that contains calls to functions that do not exist, but the module will compile successfully. However, at link time, if the function called doesn't actually exist, then you will get the error (as you're seeing now).
At least in the code snippets you showed there is no the constructor definition. It is only declared
class CConfiguration : public CConfigurationBase
{
public:
CConfiguration();
//...

LNK 2005 link errors for functions but not for class in Visual Studio 2010

I am now building a C++ DLL library. Today I have met a confusing problem: in this library I can define class but not functions. To be more specific, I give the following codes to illustrate my problem:
namespace fundamental
{
class Tree
{
public:
Tree() {};
~Tree() {};
int x;
};
/*int anyfunction()
{
return 1;
}*/
}
The above definition is in the header file, and this file will be invoked by other files. My problem is that if I commented the function part (int anyfunction()) everything was fine, but if I added this function, I would get the following errors:
page_analysis.obj : error LNK2005: "int __cdecl fundamental::anyfunction(void)" (?anyfunction#fundamental##YAHXZ) already defined in geo_box.obj
1>pa_region_properties.obj : error LNK2005: "int __cdecl fundamental::anyfunction(void)" (?anyfunction#fundamental##YAHXZ) already defined in geo_box.obj
My question is why I will get LNK2005 error only for functions but not for classes. Any ideas?
If you define something in a header file, then that definition will be duplicated in any translation unit (roughly speaking, every source file) that includes that header. Sometimes, multiple definitions are an error.
Classes can be defined in multiple translation units, as long as the definitions are identical; indeed, they must be defined in any translation unit that uses them.
Functions usually can't, but you can allow it by declaring it inline:
inline int anyfunction() {return 1;}
or you could move the definition to a single source file, and only declare it in the header:
// header
namespace fundamental {
int anyfunction();
}
// source file
int fundamental::anyfunction() {return 1;}
Most likely you have included that function via a header into different translation units (aka cpp-file). If you really need that function to be inlined, use "inline":
inline int anyfunction()
{
return 1;
}
HTH Torsten

Is there a likely / common cause of a LNK2001 unresolved external symbol error when not using any outside libraries?

I am trying to create a new instance of a class, however I am receiving a LNK2001 unresolved external symbol error when I attempt to compile my code.
As far as I can tell I have written and included the class in exactly the same manner as I included another class, in both cases -
#include "class.h" // In main.cpp
class Class { // In class.h
private:
// etc.
public:
Class();
~Class();
// etc.
};
#include "class.h" // In class.cpp
Is there a common / likely cause of these errors, or a good way I might go about finding the source of the issue?
Edit: The error is
"Error 1 error LNK2019: unresolved external symbol "class Max
__cdecl max(void)" (?max##YA?AVMax##XZ) referenced in function _main main.obj Racing "
Edit: In both cases, a class is implemented across a .h and a .cpp file included in a project. The error is only appearing with one class.
Somewhere you have written this:
Max max();
What you intended was to declare a variable max of type Max.
C++ thinks you intend to declare a function max which returns an object of type Max. This is what it is looking for.
If you just say this:
Max max;
The issue will go away.
Edit: This only occurs with constructors which take no arguments. If the constructor takes arguments, C++ can see from the parameters (which will be rvalues, e.g. constants or expressions) that it is an instantiation of the class not a function declaration.
Max max(5); // Clearly cannot be a function, because 5 is an rvalue
Or
Max max(int); // Clearly cannot be an instantiation, because int is a type
But if the constructor takes no arguments, to distinguish between them, you have to drop the brackets if you are instantiating.

VS2008 Link Error Using SafeInt3.hpp in 64bit mode

I have the below code that links and runs fine in 32bit mode -
#include "safeint3.hpp"
typedef SafeInt<SIZE_T> SAFE_SIZE_T;
SAFE_SIZE_T sizeOfCache;
SAFE_SIZE_T _allocateAmt;
Where safeint3.hpp is current version that can be found on Codeplex SafeInt. For those who are unaware of it, safeint is a template class that makes working with different integer types and sizes "safe". To quote channel 9 video on software - "it writes the code that you should".
Which is my case. I have a class that is managing a large in-memory cache of objects (>6gb) and I am very concerned about making sure that I don't have overflow/underflow issues on my pointers/sizes/other integer variables. In this use, it solves many problems.
My problem is coming when moving from 32bit dev mode to 64bit production mode. When I build the app in this mode, I'm getting the following linker warnings -
1>cachecontrol.obj : warning LNK4006: "bool __cdecl IntrinsicMultiplyUint64(unsigned __int64 const &,unsigned __int64 const &,unsigned __int64 *)" (?IntrinsicMultiplyUint64##YA_NAEB_K0PEA_K#Z) already defined in ImageInRamCache.obj; second definition ignored
1>cachecontrol.obj : warning LNK4006: "bool __cdecl IntrinsicMultiplyInt64(__int64 const &,__int64 const &,__int64 *)" (?IntrinsicMultiplyInt64##YA_NAEB_J0PEA_J#Z) already defined in ImageInRamCache.obj; second definition ignored
While I understand I can ignore the error, I would like either (a) prevent the warning from occurring or (b) make it disappear so that my QA department doesn't flag it as a problem. And after spending some time researching it, I cannot find a way to do either.
The problem is that inside safeint3.hpp, the code looks like this:
bool IntrinsicMultiplyUint64( const unsigned __int64& a, const unsigned __int64& b, unsigned __int64* pRet )
{
....
}
This means every translation unit that includes safeint3.hpp will get a definition of IntrinsicMultiplyUint64. If you are willing to modify that file, you can make those functions inline:
inline bool IntrinsicMultiplyUint64( const unsigned __int64& a, const unsigned __int64& b, unsigned __int64* pRet )
{
....
}
Are these function declared and defined in the header file and not declared as inline by any chance?
It looks like they're quasi-inlined but the symbols are visible outside the object file, which they shouldn't be.
If that's the case, simply declaring them as inline should fix the issue.
Regarding your question about disabling the warning, this should do it:
#pragma warning(disable:4006)