Undefined reference linking error when using &MyClass::MyFunction - c++

this just has me stumped, so I thought I'd query here:
I have a class as follows:
class MyClass {
public:
void myThreadFunc();
};
That's in the header. In the constructor
MyClass::MyClass() {
...
boost::thread t(boost::bind(&MyClass::myThreadFunc, this));
...
}
As I've seen done. There are NO compile time errors. However, when I link as follows:
g++ -o test.exe main.o MyClass.o /*specify boost and other libraries */
I get:
MyClass.o:MyClass.cpp:(.text+0xa4): undefined reference to `MyClass::myThreadFunc()'
collect2: ld returned 1 exit status
Which doesn't make any sense. What strikes me especially odd is that's its a linker error. I included both of my object files.
Can anyone tell me what's going on? If it might be relevant, I'm on MinGW on Windows.
EDIT:
Epic fail. I forgot the MyClass:: prefix when defining the function in my cpp file. I just didn't decide to check that. Almost as bad as forgetting a semicolin after a class definition.

You need to write a function body for MyClass::myThreadFunc() somewhere. Writing a constructor for MyClass is different from implementing the MyClass::myThreadFunc() member function.
If you call a function in C/C++, it must have a function body somewhere. That's why it's a linker error; it's trying to find the function body in all of the available object files, but you didn't write one so it can't.

Related

g++ undefined reference to a free standing function

this must have been answered a million times, yet I cannot find a suitable solution.
I have defined a free function in sensor.cpp:
std::string printTargetGasName(enalu::CombThreshold::TargetGas){}
Then I have declared the prototype of the function
in sensor.hpp
std::string printTargetGasName(enalu::CombThreshold::TargetGas);
Then I include sensor.hpp in core_enose.hpp and try to use the function in core_enose.cpp (enalu is just a namespace).
I get undefined reference linking error
core_enose.cpp:284: undefined reference to `enalu::printTargetGasName(enalu::CombThreshold::TargetGas)'
the linking instructions in the make file seem correct, i.e. the sensor.opp comes after the core_enose.opp:
g++ -g -Wall -Wextra -pedantic -std=c++11 [...] obj_dbg/core_enose.opp [...] obj_dbg/sensor.opp [...]
I also checked to see if the symbol correctly exists in the sensor.opp file:
$> nm obj_dbg/sensor.opp | grep printTarget
$> 000000000000cc9c T _Z18printTargetGasNameN5enalu13CombThreshold9TargetGasE
I have tried desperate late night measures as well, such as extern , or re including the sensor.hpp directly in the core_enose.cpp file. Nothing helps and at this point I am frustrated at the simple answer that eludes me.
Note that I am not providing code because sensor.?pp files are rather big containing a few classes that I have also been using in my program. What I describe above are the exact steps I followed to add this free function to an otherwise working application.
Could you help me?
Because your link error is about enalu::printTargetGasName, I suspect that you declared the function in your header within the enalu namespace, but the corresponding C++ doesn't have the namespace enclosure. This might fix you in the sensor.cpp file.
namespace enalu
{
std::string printTargetGasName(enalu::CombThreshold::TargetGas){}
};

if vtable is created at compile time , why this error is an linker error and not compile error?

The following piece of code give me the error
undefined reference to `vtable for Derived'
Code :
#include <iostream>
class base{
public:
base(){}
virtual ~base(){}
virtual void test()
{
}
};
class Derived:public base{
public:
Derived(){}
~Derived(){}
void test();
};
int main() {
base* b = new Derived ();
delete b;
}
which i understand is because the virtual fucntion test is declared but not defined in class Derived.
But when i compile with g++ -c file.cpp which as per this Compile or assemble the source files, but do not link. It does not give me any errors and compiles fine. Hence the above error is generated at linking time and not compile time.
From what i learned wasn't the vtable created at compile time. Then why do i not get the error at compile time itself?
However you formed the view that a vtable must be created at compile time, you are mistaken.
Separate compilation is a core concept in the standard. It is the reason that a compilation unit (aka source file) can compile, given any declaration of a function it needs - even if it doesn't have visibility of the definition.
In the typical "compile then link" build chain, this allows a compilation unit (source file) to compile, given any declaration of a function (member function or not) that might be defined in another compilation unit.
The absence of the definition of a function then needs to be detected by the linker.
Practically, this means that the compiler may emit information about the vtable, but it will be the linker that (ahem) links the specification of the vtable to the actual member functions.
Compiler doesn't require to have all methods available. It's enough for him to have their declaration.
This method could be implemented in different compilation unit (cpp/cxx file) so for compiler it's not even possible to check if this method is available somewhere else. Compiler process one cpp file at time.
It's linker job to match methods and calls together.
What I get with g++ foo.cpp -v
/tmp/ccBc4VPu.o: In function `Derived::Derived()':
foo.cpp:(.text._ZN7DerivedC2Ev[_ZN7DerivedC5Ev]+0x1f): undefined reference to `vtable for Derived'
collect2: error: ld returned 1 exit status
That's a linker error, not a compiler error per se.
The root cause of the error is that test is declared in Derived, but not actually implemented. The linker is giving a confusing error message. It should be declaring an error for the missing Derived::test method
GCC has an FAQ entry for this problem:
When building C++, the linker says my constructors, destructors or virtual tables are undefined, but I defined them
The solution is to ensure that all virtual methods that are not pure are defined. Note that a destructor must be defined even if it is declared pure-virtual [class.dtor]/7.

Undefined reference error when using a simple class inside my function

I am getting nuts with this error so I thought some of more experienced developers can help me in this regard.
I am trying to compile a sample project which uses a C++ library (named Poco). My project is linked to compiled poco libraries.
Below is my (most simplified) code:
#include "Poco/UUID.h"
class x
{
void func1()
{
new Poco::UUID(); //A
}
};
void func1()
{
new Poco::UUID(); //B
}
Now when above code is compiled, line 'A' has no error but for line 'B' linker says:
undefined reference to `Poco::UUID::UUID()'
What is the reason? When I instantiate a class from external lib in a class method no error occurs but the same code in a function produces linker error? (When I comment line B, no error occurs and linker output files are generated)
My configuration: Win7/g++/CodeLite/MinGW-4.7.1
*Update 2:*Thanks. My problem is now resolved and the issue is that I had compiled library using MSVC compiler while my application was being compiled using g++ (both under Windows platform). So I re-compiled library using g++ and everything works fine now.
Update 1: here is my IDE's output when I build my project:
C:\Windows\system32\cmd.exe /c "mingw32-make.exe -j 4 -e -f "dll1.mk" all"
----------Building project:[ dll1 - Debug ]----------
g++ -shared -fPIC -o ./Debug/dll1.so #"dll1.txt" -L. -Lc:/poco/lib -lPocoFoundationd
./Debug/PluginLibrary.o: In function `Z5func1v':
C:/Users/PARS/Documents/codelite/workspace1/dll1/PluginLibrary.cpp:12: undefined reference to `Poco::UUID::UUID()'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe: *** [Debug/dll1.so] Error 1
dll1.mk:77: recipe for target `Debug/dll1.so' failed
1 errors, 0 warnings
Your member function x::func1() is never ODR-used in that compilation unit (source file). Most compilers only generate compiled code for a member function defined inside the class definition if that member function is ODR-used within the compilation unit that is being compiled. Suppose some other source file does use x::func1(). If you compile that other source file, the compiler will produce object code for x::func1() in the object file that corresponds to that other source file.
The compiler can get away with bypassing the process of generating compiled code for x::func1() here because the class definition has to be the same across all compilation units. If you compile some other source file that has a different definition of class x you have violated the one definition rule. This is undefined behavior and no diagnosis is required.
If no source file uses x::func1() you have some dead code that just never happens to be compiled. The code has an error but it's never detected.
The compiler cannot get away with bypassing generating compiled code for the free function func1(). This function has external linkage; there's no way the compiler can tell if it might be used somewhere else. The compiler must generate compiled code for that free function.
Here's a minimum working example:
class Missing {
public:
Missing();
int value;
};
class UsesMissing {
public:
int use_missing () {
Missing missing;
return missing.value;
}
int dont_use_missing () {
return 0;
}
};
#ifdef DEFINE_USE_MISSING
int use_missing () {
Missing missing;
return missing.value;
}
#endif
int main () {
UsesMissing test;
#ifdef USE_MISSING
return test.use_missing();
#else
return test.dont_use_missing();
#endif
}
Compile with neither DEFINE_USE_MISSING or USE_MISSING defined and this compiles and links just fine with g++ and clang++. Define either one of those flags and the file fails in the link step because of the undefined reference Missing::Missing().
You should link with the correct library to fix your link (see Poco docu for the correct one).
func1 has extern linkage and so linker need Poco::UUID
whereas X::func1 is inline/private/unused.
if you use static foo1() or inline foo1() the linker error disappears
if you use x::func1 or implement x::func1 outside of the class x{}; the error linker appears

Strange output when compiling c++ code. Any Ideas?

When i compile my code i get a set of errors that appear to related to the output files as in the .o file. I'm not sure why these sorts of errors would occur. Any Ideas?
/tmp/ccjPLJVV.o: In function `PubSub::~PubSub()':
Video_process.cpp:(.text._ZN6PubSubD2Ev[_ZN6PubSubD5Ev]+0x12): undefined reference to `vtable for PubSub'
/tmp/ccjPLJVV.o: In function `main':
Video_process.cpp:(.text.startup+0x34): undefined reference to `vtable for PubSub'
Video_process.cpp:(.text.startup+0xeb): undefined reference to `PubSub::run()'
/tmp/ccjPLJVV.o:(.rodata._ZTI13Video_process[typeinfo for Video_process]+0x10): undefined reference to `typeinfo for PubSub'
collect2: ld returned 1 exit status
This is essentially the output i'm getting when I attempt to compile.
It appears you have unimplemented virtual methods.
class PubSub
{
//virtual destructors, although pure
//MUST have an implementation
virtual ~PubSub() = 0 { }
/*virtual?*/ void Run(); // <--- have you implemented this one?
};
Maybe you've implemented the method, but you have not linked it. If you're using GCC, -o flag is your friend; all your class .o files must be specified when compiling the main.cpp.
this is an error message from the linker, not the compiler. The linker cannot find some symbols which are declared, but not defined, in some files it tries to link together to make (most likely) an executable. The solution is to provide the definitions, i.e. the (compiled) code with those definitions. That code may already exist and you just have to "link against it" (tell the linker to search for symbols there) or may not, in which case you have to provide it...
for example, add the file defining the implementations of class PubSub to the linker/compiler command line should help ...

Class issue with main C++

I created my header file for a class and #included "theclassname.h" in main.cpp but when I try to compile I get "undefined reference to "ClassName::TheConstructor(bool, int*, std::basic_string, std::allocator >)""
I coded the constructor and a function called "ClassName::start" inside of my Classname.cpp file but for some reason it is giving this undefined reference issue for this start function and for my destructor which is also coded in my cpp file. Every call I make in main to a function that was coded inside of the header file doesn't trigger this error but every call made to a function coded in my .cpp file triggers this.
I've seen a lot of posts about this but I've coded them properly with the correct parameters and return types and made sure the function name was the same as the one defined in the header file. What else could be causing this besides misspelling something because I've checked for that over 10 times.
Thanks
#ifndef THECLASSNAME_H
#define THECLASSNAME_H
#include <iostream>
class TheClassName {
public:
TheClassName(bool theBool=true, int *theArray=0,
std::string message="-1");
~TheClassName();
void start();
void setBool(bool theBool) {aBool=theBool;}
bool getBool() {return aBool;}
void setMessage(std::string message) {mssg=message;}
std::string getMessage() {return mssg;}
std::string getHello() {return hello;}
private:
int *anArray;
bool aBool;
std::string mssg;
std::string hello;
void aFunction1(bool);
void aFunction2();
void aFunction3();
void aFunction4();
};
#endif
Sorry Everyone just fixed it! In my makefile I did
exec1: main.o classname.o
g++ -o exec1 main.o
Instead of
exec1: main.o classname.o
g++ -o exec1 main.o classname.o
Thank you guys so much!
That sounds like you're getting the error at the linker phase. Are you also compiling the file that you have the C++ class definition in and not just including the header file? You need to have a separate C++ file with the function definitions for you class, compile this file as well and include the object file in the linker command line so you don't get your undefined reference errors when you link the final executable.
Please post your code and also post the build command and output, if possible.
This is a linkage rather than compilation problem and it sounds like the compilation unit containing your constructor and destructor declarations have not been linked into the executable - in other words, the linker can't find your functions.