I am new to C++, so I am sorry if this a simple or obvious error. I have been reading a lot other questions and the documentation, but I haven't been able to find a solution yet.
I am trying to add a new class definition to a large existing project. Everything compiles perfectly fine without my additions. However, when I add my code below I get a LNK2019 error on the constructor method (and any additional method). I have noticed adding/referencing properties does not cause this linker error, only the methods. Below is the most simple example that produces the error:
Header:
namespace foo
{
class bar_interface
{
public:
//My code
#ifndef Point_H
#define Point_H
class Point
{
public:
Point(int x, int y);
};
#endif
//existing code
void onStartup();
}
}
Class:
//My code
#ifndef Point_H
#define Point_H
class foo:bar_interface::Point{
public:
Point(int x, int y)
{
};
};
#endif
//existing code
void bar_interface::onStartup()
{
foo::bar_interface::Point p( (int)8, (int)8 );
//continue existing code
}
Error 1 error LNK2019: unresolved external symbol "public: __thiscall
foo::bar_interface::Point::Point(int,int)"
(??0Point#bar_interface#foo##QAE#HH#Z)
referenced in function "public: void __thiscall
foo::bar_interface::onStartup(void)"
(?onStartup#bar_interface#foo##QAEXXZ)
I realize that probably do not need such explicit calls to Point or casting the numbers as ints, but I wanted to make sure I wasn't missing anything obvious (removing them doesnt change the error). I have tried moving the 'Point' class to its own file and defining it outside the 'bar_interface' but within the 'foo' namespace. Removing the #ifndef code creates a C2011 redefinition error. I am at a loss for how to proceed.
Unresolved external means that the definition is missing, that is that the linker cannot find an implementation of the named function.
Somewhere you need:
namespace foo
{
bar_interface::Point::Point(int,int)
{ ... }
}
Remove all your lines from the code above that start from # and the reason of the issue becomes cleaner.
Related
I have the following code (more than one file involved)...
//--- SomeInterface.h
struct SomeInterface
{
virtual void foo() = 0;
virtual ~SomeInterface(){}
};
//--- SomeInterfaceUser.h
#include <memory> //shared_ptr
class SomeInterface;
//NOTE: struct SomeInterface... causes linker error to go away...
class SomeInterfaceUser
{
public:
explicit SomeInterfaceUser(std::shared_ptr<SomeInterface> s);
};
//SomeInterfaceUser.cpp
#include "SomeInterfaceUser.h"
#include "SomeInterface.h"
SomeInterfaceUser::SomeInterfaceUser(std::shared_ptr<SomeInterface> s)
{
}
//SomerInterfaceUserInstantiator.cpp
#include "SomeInterfaceUser.h"
#include "SomeInterfaceImpl.h"
struct SomeInterfaceImpl : SomeInterface
{
virtual void foo(){}
};
void test()
{
SomeInterfaceUser x{std::make_shared<SomeInterfaceImpl>()};
}
Using the Visual C++ compiler, I get a linker error (LNK2019). Using GCC 4.8.4 this is not the case. Changing the forward declaration class SomeInterface to struct SomeInterface makes the linker error go away. I always thought that one should be able to use class/struct interchangeably? The interface of SomeInterfaceUser should not depend on whether SomeInterface is defined as class or struct, not so?
Is this a Visual C++ bug. I cannot find anything relating to it. I suspect the fact that the struct is used as template parameter has something to do with it.
Your help appreciated.
I've just been facing the same problem with both VC++ 2010 and VC++ 2017, and after some tests I've found that the problem resides in the symbol name the compiler gives to structs and classes internally.
Here a minimum example consisting in three files:
main.cpp
#include "bar.h"
struct Foo {};
int main() {
Foo foo;
bar(&foo);
return 0;
}
bar.h
class Foo;
void bar(Foo* f);
bar.cpp
#include "bar.h"
void bar(Foo* foo) {}
When the project is compiled the following errors and warnings appear:
warning C4099: 'Foo': type name first seen using 'class' now seen using 'struct'
see declaration of 'Foo'
error LNK2019: unresolved external symbol "void __cdecl bar(struct Foo *)" (?bar##YAXPAUFoo###Z) referenced in function _main
fatal error LNK1120: 1 unresolved externals
Now, I swapped the struct and class declarations, so main.cpp and bar.h are now:
main.cpp
#include "bar.h"
class Foo {};
int main() {
Foo foo;
bar(&foo);
return 0;
}
bar.h
struct Foo;
void bar(Foo* f);
As expected, the error still pops up:
error LNK2019: unresolved external symbol "void __cdecl bar(class Foo *)" (?bar##YAXPAVFoo###Z) referenced in function _main
BUT, and this is the interesting part, see that the symbols for the expected function (the one used in main()) in each case differ:
?bar##YAXPAUFoo###Z (when the parameter is a struct)
?bar##YAXPAVFoo###Z (when the parameter is a class)
Conclusion
The compiler gives slightly different names if the type is a struct or a class.
The linker then cannot find the proper definition because it is looking for a different one: bar.cpp defines one with the forward declaration, but for the moment it is called in main.cpp the actual declaration has taken placed, so a different function name is given in the symbols table.
Update (2023-02-03)
I've just seen that clang is able to report this issue:
error: 'Foo' defined as a struct here but previously declared as a class; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Werror,-Wmismatched-tags]
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I've been developing C# and Java (among many other languages) for many years, and I'm just now getting my feet wet in C++. I've buried myself in resources on inheritance and classes, but I just can't seem to figure out how to get rid of this pesky error.
My code:
Entity.h:
#ifndef ENTITY_H
#define ENTITY_H
#include <iostream>
class Entity
{
public:
std::string m_name;
void update(float delta);
Entity();
private:
virtual void step(float delta);
};
#endif
Entity.cpp:
#include "Entity.h"
Entity::Entity()
{
m_name = "Generic Entity";
}
void Entity::update(float delta)
{
step(delta);
}
void Entity::step(float delta) {}
Player.h:
#ifndef PLAYER_H
#define PLAYER_H
#include "Entity.h"
class Player : public Entity
{
public:
Player();
private:
virtual void step(float delta);
virtual void draw() const;
};
#endif
Player.cpp:
#include "Player.h"
Player::Player()
{
m_name = "Player";
}
void Player::step(float delta) {}
void Player::draw() const {}
Main.cpp:
int main()
{
return 0;
}
As you can see, I'm not doing anything with the classes, but I'm getting these errors:
Error 3 error LNK1120: 1 unresolved externals C:\[...]\Debug\ConsoleApplication1.exe ConsoleApplication11
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Entity::Entity(void)" (??0Entity##QAE#XZ) referenced in function "public: __thiscall Player::Player(void)" (??0Player##QAE#XZ) C:\[...]\ConsoleApplication1\Player.obj ConsoleApplication1
UPDATE: The code magically works when I comment out the following code in Player.cpp:
/*Player::Player()
{
m_name = "Player";
}*/
It looks like Entity isn't linked to player. Make sure output shows it compiling and that they are both added to your project
You also need to define a virtual destructor in your base class
Edit:
It doesn't have to compile first, my mistake. In C/C++, program creation is in two steps. First the compiler creates obj files for your cpp files, such as Entity.obj, Player.obj and so on. Then the linker will bundle everything together.
In Player.cpp, you say that you will have a class named Entity at some point, so the compiler finds the definition of that class in the .h file. Player.cpp then gets transformed into executable code in Player.obj but it won't contain the Entity.obj executable code. The compilation step works.
Then the linker will try to parse Player.obj and find Entity.obj that the compiler said will exists. If it doesn't then you get the "undefined reference" error, because the definitions found do not match the actual executable.
The virtual destructor is mandatory. The way inheritance works in C++ is with the virtual table. For each class with inheritance, a virtual table (vtable) is created with the virtual entries. When the linking step is performed, the linker will fill the vtable with the actual function. When the code executes, it checks the vtable for that class then execute that function. This allows you to "override" base methods or use the base method if nothing new is added. The virtual destructor creates the entry in that table for the destructor. If there is no entry for a virtual destructor, then the child class will not have an entry and won't be able to destroy the base class properly, which results in undefined behavior
EDIT: I know there are similar questions, but I cannot find an answer to a following issue: Why the methods inside the class are working correctly and outside are not.
I've got a weird problem in my project which I'm developing in MSVC++ 2012. My project consists of different modules of code. The important modules from the problem's point of view is a library and the GUI. They exist as different projects in the same solution.
I have some methods in the library which are part of the classes (in this case Calibration3D):
void Calibration3D::load(const std::string &path)
I use it without problems when I need it in the GUI, however I need to use a following method (outside the class):
void xxxyyy()
But when I'm trying to use that function (outside the class but in the same namespace) I get a following error:
1>project_xml.obj : error LNK2001: unresolved external symbol "void __cdecl cci::xxxyyy(void)" (?xxxyyy#cci##YAXXZ) 1>D:\praca_pw\cci\build-msvc2012\x64\Release\\ccigui.exe : fatal error LNK1120: 1 unresolved externals
Anybody knows how to solve it?
When I have a header file like this:
namespace xyz {
void foo();
class bar { ... };
}
then I write the cpp file like this:
#include "xyz.h"
namespace xyz {
void foo() { ... }
bar::bar() { ... }
}
This means I have to type a lot less and make fewer mistakes with regard to namespaces.
OK, solved, it seems that when a method is defined inside the namespace in header file, it should also be defined explicitly as part of namespace in implementation file, in this case:
cci::xxxyyy()
{
...
}
will work and
xxxyyy()
{
...
}
will not.
I have two classes, one inherited from the other. When I compile, I get the following errors:
Entity.obj : error LNK2019: unresolved external symbol "public: __thiscall Utility::Parsables::Base::Base(void)" (??0Base#Parsables#Utility##QAE#XZ) referenced in function "public: __thiscall Utility::Parsables::Entity::Entity(void)" (??0Entity#Parsables#Utility##QAE#XZ)
Entity.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall Utility::Parsables::Base::~Base(void)" (??1Base#Parsables#Utility##UAE#XZ) referenced in function "public: virtual __thiscall Utility::Parsables::Entity::~Entity(void)" (??1Entity#Parsables#Utility##UAE#XZ)
D:\Programming\Projects\Caffeine\Debug\Caffeine.exe : fatal error LNK1120: 2 unresolved externals
I really can't figure out what's going on.. can anyone see what I'm doing wrong? I'm using Visual C++ Express 2008. Here are the files..
"include/Utility/Parsables/Base.hpp"
#ifndef CAFFEINE_UTILITY_PARSABLES_BASE_HPP
#define CAFFEINE_UTILITY_PARSABLES_BASE_HPP
namespace Utility
{
namespace Parsables
{
class Base
{
public:
Base( void );
virtual ~Base( void );
};
}
}
#endif //CAFFEINE_UTILITY_PARSABLES_BASE_HPP
"src/Utility/Parsables/Base.cpp"
#include "Utility/Parsables/Base.hpp"
namespace Utility
{
namespace Parsables
{
Base::Base( void )
{
}
Base::~Base( void )
{
}
}
}
"include/Utility/Parsables/Entity.hpp"
#ifndef CAFFEINE_UTILITY_PARSABLES_ENTITY_HPP
#define CAFFEINE_UTILITY_PARSABLES_ENTITY_HPP
#include "Utility/Parsables/Base.hpp"
namespace Utility
{
namespace Parsables
{
class Entity : public Base
{
public:
Entity( void );
virtual ~Entity( void );
};
}
}
#endif //CAFFEINE_UTILITY_PARSABLES_ENTITY_HPP
"src/Utility/Parsables/Entity.cpp"
#include "Utility/Parsables/Entity.hpp"
namespace Utility
{
namespace Parsables
{
Entity::Entity( void )
{
}
Entity::~Entity( void )
{
}
}
}
The relevant bit is this:
unresolved external symbol "public: __thiscall Utility::Parsables::Base::Base(void)"
You need to provide a definition for Base::Base and Base::~Base. A declaration is not good enough. Even if you have nothing to do in either function, you need to leave an empty function body, because C++ actually requires the function to exist. C++ puts things like virtual table maintenance inside your constructors and destructors, so they must be defined even if you don't need to do anything there -- C++ has to do things in there.
Are you sure Base.cpp is being included in the build?
Just encountered this exact same error today in Visual Studio 2015. Unfortunately the accepted answer didn't worked (as well as answers from many same questions). The thing that worked for me was right click on the base class cpp file, exclude and then include it again. I think somehow VS got confused while moving file around and renames and it just silently refused to compile it even though it was marked as "Included In project" = true in property editor as well as listed in vcproj file in group. This is horrible error and ended up spending good hour on it.
Either your base.cpp is not being compiled/linked or you have a misspelling in it
I want to have some data cache which contains some objects which I can update over an UpdateCache function. However, I'm getting problems with a LNK2001 followed by a LNK1120.
HeaderFile.h
#ifndef headerfile_included
#define headerfile_included
#include <vector>
struct MyObject {
unsigned int A;
unsigned int B;
};
class MyClass {
private:
static std::vector<MyObject> myObjectCache;
public:
static void UpdateCache ();
};
#endif
CodeFile.cpp
#include "HeaderFile.h"
void MyClass::UpdateCache () {
myObjectCache.clear();
/* Repopulate cache with new data */
}
The error message I get from the linked is
error LNK2001: unresolved external symbol ""private: static class std::vector > MyClass::myObjectCache" (?myObjectCache#MyClass##0V?$vector#UMyObject##V?$allocator#UMyObject###std###std##A)".
fatal error LNK1120: 1 unresolved externals
My opinion is that it is some problem with the partitioning into the header file and the code file as I have had similar problems with improper partitioning. If it is again such a problem, it would be nice if you could post some rule on what to put into the header file and what into the code file since it's pretty confusing.
You need to add this to a cpp file:
std::vector<MyObject> MyClass::myObjectCache;
The reason is that as a static exists without a class ever being instantiated it needs to exist whether an instance of the class is instantiated or not. The line above creates the instance of the static and thus it exists whether or not you ever create an instance of the class itself.
Since your vector is static, essentially a global entity as far as the compiler is concerned, you need to be sure to give it a home in a compilation unit. That's why you have to do what #Goz says and do
std::vector<MyObject> MyClass::myObjectCache;