This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
Ok so I'm still getting used to C++ again, so this error may seem simple. I'm attempting to create a simple class with a three member functions (I'm only trying to call one of them in this). So I create the class, instantiate an object, then attempt to call the function using that object and this error comes up:
Code.cpp:(.text+0x15): undefined reference to `Code::genCode()'
I've double checked to see if it was an error with the function itself, but that is not the case. I've seen others post about this issue but there seems to be a multitude of situations and solutions. Anyway here's the code:
#include <vector>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <list>
using namespace std;
class Code {
public:
int genCode();
int checkCorrect();
int checkIncorrect();
};
int main()
{
Code c1;
c1.genCode();
}
////////////////FUNCTIONS/////////////////////////
int genCode()
{
vector <int> newcode;
srand(time(NULL));
for(int i = 0; i < 9; i++){
int x;
x = (rand() % 6);
if (find(newcode.begin(),newcode.end(), x) == newcode.end())
{
newcode.push_back(x);
}
}
if (newcode.size() > 4)
{
newcode.pop_back();
}
for(int i = 0; i < 4; i++)
{
return newcode[i];
}
}
int checkCorrect()
{
}
int checkIncorrect()
{
}
you need to put class name before method name
the format is
'returnType Classname::methodname
{
codes
}'
int code::genCode()
{
//codes
}
or you also possible to write code in class
Change the implementation of the methods of your class to the following:
int Code::genCode()
{
...
}
int Code::checkCorrect()
{
...
}
int Code::checkIncorrect()
{
...
}
You are defining the functions outside the class. Put them inside the class, then you don't need to declare them inside the class. Directly define them.
#include <vector>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <list>
using namespace std;
class Code {
public:
////////////////FUNCTIONS/////////////////////////
int genCode()
{
cout << "Inside genCode. Just for Debugging purpose." << endl;
vector <int> newcode;
srand(time(NULL));
for(int i = 0; i < 9; i++){
int x;
x = (rand() % 6);
if (find(newcode.begin(),newcode.end(), x) == newcode.end())
{
newcode.push_back(x);
}
}
if (newcode.size() > 4)
{
newcode.pop_back();
}
for(int i = 0; i < 4; i++)
{
return newcode[i];
}
}
int checkCorrect()
{
}
int checkIncorrect()
{
}
};
int main()
{
Code c1;
c1.genCode();
}
Otput:
Inside genCode. Just for Debugging purpose.
The function
int genCode()
Is what's called a free function. It is not bound to a class.
In order for the compiler to know that genCode is part of a class, you have to tell it by explicitly stating the namespace to which genCode belongs.
int Code::genCode()
However since it appears code Code is entirely contained within one file, following CodeRunner's advice will lead to a cleaner implementation.
But why would anyone want to got the trouble of splitting everything up?
Separating the class definition from the method implementations allows you place the class definition into one file, the 'h header file, and the methods in an implementation file, usually a .cpp file. The header file is then shared with users of the Code object and the implementation file can be compiled into a library and hidden from the callers view.
There are a number of reasons to do this, but most of them have to do with creating pre-compiled libraries and using them to reduce build times.
With a library, you build the library once, and then compile the rest of the code that uses the library over and over until you get it right. Can you imagine how long it would take to build a program if you had to rebuild the C++ standard library every time you fixed a bug and wanted to test?
Had a job like that once. Had to spend four hours compiling third party network code every time I made a fix because the company's paranoid build system rebuilt everything every time. Off by one error? 4 hours. Need to add a debug line? 4 hours. You could make and test three changes a day. Sure, you can batch up a bunch of fixes, but if one failed spectacularly and broke the system, which one was it? Sooner or later you're reduced to a crawl, making tweaks, building, testing, profiling one at a time. Fortunately I was working on contract and paid by the hour.
Another good example is you can have one library that supports Windows and other libraries supporting QNX and other operating systems. All use the same header and the user can write a program that, in theory, will operate on all supported platforms simply by recompiling the user's code. It's never quite that clean, but one can dream.
The library can even be replaced with an updated library without requiring changes or compilation of the user's code and different variants of the library can exist for different needs. A debug version with extra logging, for example.
Perhaps the implementation is not intended for public eyes. The users get to see the header and call functions in the library, but no more.
Related
Overview
I am trying to develop a C++ application which allows for user-created plugins.
I found a nice library called Pluma (http://pluma-framework.sourceforge.net/) which functionally seems to be exactly what I want.
After going through their tutorial, I was able to (with a bit of difficulty) convince the plugin to compile. However, it refuses to play nice and connect with the main program; returning various errors depending on how I try to implement them.
Problem
If I comment out the line labeled 'Main problem line' (in the last file, main.cpp), the plugin compiles successfully, and the main app can recognize it, but it says that "Nothing registered by plugin 'libRNCypher'", and none of the functions can be called.
If I compile that line, the main application instead says "Failed to load library 'Plugins/libRNCypher.so'. OS returned error: 'Plugins/libRNCypher.so: undefined symbol: _ZTIN5pluma8ProviderE".
My guess is that it has something to do with the way the plugin was compiled, as compiling it initially did not work and Code::Blocks told me to compile with "-fPIC" as a flag (doing so made it compile).
Code
Code below:
Main.cpp
#include "Pluma/Pluma.hpp"
#include "CryptoBase.h"
int main()
{
pluma::Pluma manager;
manager.acceptProviderType< CryptoBaseProvider >();
manager.loadFromFolder("Plugins", true);
std::vector<CryptoBaseProvider*> providers;
manager.getProviders(providers);
return 0;
}
CryptoBase.h
#ifndef CRYPTOBASE_H_INCLUDED
#define CRYPTOBASE_H_INCLUDED
#include "Pluma/Pluma.hpp"
#include <string>
#include <vector>
#include <bitset>
//Base class from which all crypto plug-ins will derive
class CryptoBase
{
public:
CryptoBase();
~CryptoBase();
virtual std::string GetCypherName() const = 0;
virtual std::vector<std::string> GetCryptoRecApps() const = 0;
virtual void HandleData(std::vector< std::bitset<8> > _data) const = 0;
};
PLUMA_PROVIDER_HEADER(CryptoBase)
#endif // CRYPTOBASE_H_INCLUDED
RNCypher.h (This is part of the plugin)
#ifndef RNCYPHER_H_INCLUDED
#define RNCYPHER_H_INCLUDED
#include <string>
#include <vector>
#include <bitset>
#include "../Encoder/Pluma/Pluma.hpp"
#include "../Encoder/CryptoBase.h"
class RNCypher : public CryptoBase
{
public:
std::string GetCypherName() const
{
return "RNCypher";
}
std::vector<std::string> GetCryptoRecApps() const
{
std::vector<std::string> vec;
vec.push_back("Storage");
return vec;
}
void HandleData(std::vector< std::bitset<8> > _data) const
{
char letter = 'v';
_data.clear();
_data.push_back(std::bitset<8>(letter));
return;
}
};
PLUMA_INHERIT_PROVIDER(RNCypher, CryptoBase);
#endif // RNCYPHER_H_INCLUDED
main.cpp (This is part of the plugin)
#include "../Encoder/Pluma/Connector.hpp"
#include "RNCypher.h"
PLUMA_CONNECTOR
bool connect(pluma::Host& host)
{
host.add( new RNCypherProvider() ); //<- Main problem line
return true;
}
Additional Details
I'm compiling on Ubuntu 16.04, using Code::Blocks 16.01.
The second error message seems to not come from Pluma itself, but a file I also had to link, #include <dlfcn.h> (which might be a Linux file?).
I would prefer to use an existing library rather than write my own code as I would like this to be cross-platform. I am, however, open to any suggestions.
Sorry for all of the code, but I believe this is enough to reproduce the error that I am having.
Thank You
Thank you for taking the time to read this, and thank you in advance for your help!
All the best, and happy holidays!
I was not able to reproduce your problem, however looking at
http://pluma-framework.sourceforge.net/documentation/index.htm,
I've noticed that:
in your RNCypher.h file you miss something like
PLUMA_INHERIT_PROVIDER(RNCypher, CryptoBase)
it seems also that there's no file CryptoBase.cpp containing something like
#include "CryptoBase.h"
PLUMA_PROVIDER_SOURCE(CryptoBase, 1, 1);
finally, in CryptoBase.h I would declare a virtual destructor (see Why should I declare a virtual destructor for an abstract class in C++?) and provide a definition to it, while you should not declare a default constructor without providing a definition to it (see for instance Is it correct to use declaration only for empty private constructors in C++?); of course the last consideration is valid unless there's another file in which you have provided such definitions.
I'm making my first attempt at unit testing in C++, and I haven't used C++ in a number of years (I'm mainly a C# coder at the moment). It seems like I'm making a right pig's ear of it - I hope someone can steer me back onto the righteous path. I'm just getting started here and would really like to be implementing these tests using the best practice possible, so any and all comments are welcome, even though I'm most concerned with my linker error at present.
So, I have an overall solution "Technorabble", with sub-projects "CalibrationTool" and "CalibrationToolUnitTests".
CalibrationTool has a MathUtils.h file:
#ifndef __math_utils__
#define __math_utils__
#include "stdafx.h"
#include <vector>
namespace Technorabble
{
namespace CalibrationTool
{
double GetDoubleVectorAverage(std::vector<double> v)
{
double cumulativeValue = 0;
for(std::vector<double>::iterator iter = v.begin(); iter != v.end(); ++iter)
{
cumulativeValue += *iter;
}
return cumulativeValue / v.size();
}
}; // end namespace CalibrationTool
}; // end namespace Technorabble
#endif // !__math_utils__
(But no .cpp file as I was having all kinds of (somewhat similar) issues getting my template function working - so I ended up defining that inline).
Moving on to the Unit Tests project, I have a main.cpp:
#include "MathUtilsTest.h"
void RunMathUtilsTests();
int main()
{
RunMathUtilsTests();
// Other class tests will go here when I have things to test
}
void RunMathUtilsTests()
{
MathUtilsTest* mathUtilsTest = new MathUtilsTest();
mathUtilsTest->RunTests();
delete mathUtilsTest;
}
Finally, the header and cpp for the MathUtilsTest class, again, fairly simple:
.h:
#ifndef __MATH_UTILS_TEST__
#define __MATH_UTILS_TEST__
#include "CalibrationToolUnitTestsLogging.h"
#include "..\CalibrationTool\MathUtils.h"
class MathUtilsTest
{
public:
MathUtilsTest();
~MathUtilsTest();
bool RunTests();
private:
bool GetDoubleVectorAverageTest();
}; // end class MathUtilsTest
#endif
.cpp:
#include "MathUtilsTest.h"
#include <sstream>
bool MathUtilsTest::RunTests()
{
return GetDoubleVectorAverageTest();
}
MathUtilsTest::~MathUtilsTest()
{
}
MathUtilsTest::MathUtilsTest()
{
}
bool MathUtilsTest::GetDoubleVectorAverageTest()
{
bool passed = true;
std::vector<double> values;
for (int i = 1; i < 23; i++)
{
values.push_back(i);
}
// vector becomes: 1, 2, 3, 4, .....20, 21, 22. Average is 11.5
double expectedAverage = 11.5;
double calculatedAverage = Technorabble::CalibrationTool::GetDoubleVectorAverage(values);
if (calculatedAverage != expectedAverage)
{
std::ostringstream s;
s << calculatedAverage;
std::string avgString = s.str();
CalibrationToolUnitTestsLogging::Write("Failed MathUtilsTest.GetDoubleVectorAverageTest: " + avgString);
passed = false;
}
else
{
CalibrationToolUnitTestsLogging::Write("Passed MathUtilsTest.GetDoubleVectorAverageTest");
}
return passed;
}
This all seemed fine to me, I'm protecting my header with #ifndef, etc. But I'm still getting the following errors:
1) error LNK1169: one or more multiply defined symbols found
2) error LNK2005: "double __cdecl Technorabble::CalibrationTool::GetDoubleVectorAverage(class std::vector >)" (?GetDoubleVectorAverage#CalibrationTool#Technorabble##YANV?$vector#NV?$allocator#N#std###std###Z) already defined in main.obj C:_SVN\Technorabble\Windows Software\CalibrationToolUnitTests\MathUtilsTest.obj
How can this be? Can anyone spot where it's going wrong?
Functions defined in headers should be marked as inline:
inline double GetDoubleVectorAverage(std::vector<double> v)
{
}
If it's longer than a couple of lines, consider moving it to an implementation file.
pragmas or include guards don't protect against multiple definitions.
Note that you should pass v by const reference rather than by-value.
You are defining a function GetDoubleVectorAverage in a header. This means that it will be defined in every translation unit (i.e. every source file) that includes that header. If your program contains more than one such translation unit, then you'll have more than one definition - which isn't allowed.
Solutions are:
Add inline to the function definition, to relax this rule and allow multiple identical definitions; or
Move the function definition into a source file, and only declare it in the header.
I'm protecting my header with #ifndef
That only prevents the header from being included more than once within the same translation unit. It doesn't prevent inclusion from more than one unit.
Also, you shouldn't use a reserved name like __math_utils__ as a header guard, even if the internet is littered with examples of dodgy code doing that.
I was having all kinds of (somewhat similar) issues getting my template function working
Templates usually need to be defined in header files, to make the definition available at the point of use. Function templates are implicitly inline, but normal functions (like this one) aren't.
I was working on a project and started a new class. I wanted to use a vector to store pointers of functions and then call them. Getting the function pointer and calling it was not a problem, however storing them was. I tried storing them in a vector, but it keeps emptying itself. I've tried making the vector a member of a class and an extern, both don't work. I've never had this problem ever before, and I have no clue why this is happening. Here is my current code:
TickHandler.h:
#include <iostream>
#include <ctime>
#include <vector>
class tickHandler {
public:
void addTickingFunction(void(*func)());
void onTick(void);
std::vector<void(*)()>funcs;
};
extern tickHandler TickHandler;
TickHandler.cpp:
#include "TickHandler.h"
tickHandler TickHandler;
void tickHandler::addTickingFunction(void(*func)())
{
funcs.push_back(func);
std::cout << funcs.size() << std::endl;
}
void tickHandler::onTick()
{
std::cout << funcs.size() << std::endl;
for (int i = 0; i< funcs.size();i++)
{
funcs[i]();
}
}
The expected output would be:
1
1
but instead it is:
1
0
Any help would be greatly appreciated.
EDIT: There is a lot of code in the project, but the class is only being accessed by 2 functions:
TickHandler.addTickingFunction(&physicsTick);
and
TickHandler.onTick();
Firstly, I'd suggest you put some guards around that header file, e.g.:
#ifndef TICKHANDLER_H
#define TICKHANDLER_H
// Class declaration.
#endif
I am taking a shot in the dark here, but I think your problem is that you are adding your physics tick functions to one instance of a tick handler, but running them in another. I don't think they are disappearing.
You've somehow got two instances of the TickHandler class lying about. Given this is C++ and it is an object-orientated language, the extern TickHandler and the global instance created in your .cpp file is setting off alarm bells for me.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I have a trouble with finding answer for my questions (Q), so I registered here to ask you guys how it really works (or don't works) ;)
I am writing in c++, in Visual Studio 2012, but still don't really know how it is with #includes, namespaces etc. in header files. Do I even need to use them?
(Q1): Let's say I have one .cpp file and few .h files, which are using, for example: vectors, things from <algorithm>, <ctime> and some other libraries, but I do not write #include <something> in header files, only in .cpp. Is it correct? Or should I include everything I use in every header?
Usually everything works for me, I can even say it always "works", because I don't have too much experience yet and I was usually containing everything in one .cpp and 1 or 2 headers with some void functions. But don't know if it works because it should, or because, for example, mu compiler allows that and in some issues it can cause errors.
(Q2): Now a thing about using namespace std;
In some cases functions in .h files works without it, but sometimes not. For example, the voids that are working (just simple voids for merge-sort):
#ifndef LISTA_1_H
#define LISTA_1_H
#include "Lista_0_Zadanie_1.h"
void MERGE(vector<double> &A, int p, int q, int r)
{
int i = p;
int j = q+1;
int lenght = r - p + 1;
int k=0;
vector<double> merged;
merged.assign (lenght,0);
while((i<=q)&&(j<=r))
{
if(A[i] <= A[j])
{
merged[k]=A[i];
++i;
}
else
{
merged[k]=A[j];
++j;
}
k++;
}
if(j<=r)
{
while(j<=r)
{
merged[k]=A[j];
++j;
++k;
}
}
if(i<=q)
{
while(i<=q)
{
merged[k]=A[i];
++i;
++k;
}
}
for (i=0;i<lenght;++i)
A[p+i]=merged[i];
}
void MERGESORT(vector<double> &A, int k, int l)
{
if(k<l)
{
int m = (k+l)/2;
//int mp = m+1;
// cout << "koza"<<endl;
MERGESORT(A,k,m);
MERGESORT(A,m+1,l);
MERGE(A,k,m,l);
}
}
void TRIPLE_MERGESORT(vector<double> &A, int k, int l)
{
if(k<l)
{
int one_third = (l-k)/3;
int two_third = 2*(l-k)/3; // k < k+one_third < k+two_third < l
TRIPLE_MERGESORT(A,k,k+one_third);
TRIPLE_MERGESORT(A,k+one_third+1,k+two_third);
TRIPLE_MERGESORT(A,k+two_third+1,l);
MERGE(A,k,k+one_third,k+two_third);
MERGE(A,k,k+two_third,l);
}
}
void INSERT_MERGESORT (vector<double> &A, int k, int l)
{
if(l<19) // l=n-1, więc n<20 <=> l < 19
{
double y;
int i,j;
for(i=0; i<l+1; ++i)
{
y = A[i];
j = i-1;
while((j>=0) && (A[j]>y) )
{
A[j+1] = A[j];
--j;
}
A[j+1]=y;
}
}
else
MERGESORT(A,k,l);
}
#endif
... and in some cases it does not work, if I do not write "using namespace std;" or add " std:: " in correct place (here before vectors), it does not work:
#ifndef SCHEMAT_HORNERA_H
#define SCHEMAT_HORNERA_H
//using namespace std;
void HORNER( int n, double z0, double p_z0, vector<double> a, vector<double> &B)
{
B[n] = a[n];
for(int k = n-1; k>=0; --k)
{
B[k] = a[k] + z0*B[k+1];
}
}
#endif
So here's my question: Should I always use "std::" or "using namespace std"?
If yes, why are my files until now "working"? Because in some cases VS allows for that, while it is not correct and some compilers and not allow for this?
Q1) Whether or not you need to #include a header with a full definition depends on if you need a full definition, or if just a forward-declare will do. In the case of needing just a forward-declaration, all you need to tell the compiler is the name of something. An example is if you need a pointer-to-something:
// fw-decl Foo
class Foo;
// define Gizmo
class Gizmo
{
public:
void DoIt();
Foo* mFoo; // just need a pointer, so don't need a full definition of foo
};
Later you will need a full definition if you actually use the Foo object, as with:
#include "foo.h"
#include "gizmo.h"
void Foo::DoIt()
{
mFoo->DoSomething(); // now we need a full definition
}
On the other hand, if the compiler needs to know for example how big Foo is, then you need a full definition.
#include "foo.h"
class Gizmo
{
public:
Foo mFoo; // need a full definition here
};
As a general rule of thumb, it is best to provide full definitions only when necesarry, so as to keep compilation times as quick as possible.
Q2) Simplified rule-of-thumb: never using namespace std. If you simply follow this rule of thumb without ever thinking about it, you will never have problems with namespace collisions, polluting the global namespace, or other nastiness.
Of course, this rule of thumb is a little over-simplified for those who actually think for a living, so here's a slightly better one:
1) Never using namespace in a header
2) Never using namespace in a source file unless it's your own namespace you're implementing.
Rules of thumb can be overly restrictive, and this is no exception, but it will get you on your way without venturing too far in to a landmine. The problem with using anmespace is it brings whatever is in that namespace in to global scope. Suppose you have your own header file:
mystring.h
namespace MyString
{
class string
{
// ...
};
}
...and then in the source file:
#include "mystring.h"
#include <string>
using namespace MyString;
using namespace std;
string s; // OOPS: which "string" is this? MyString::string, or std::string?
This ambiguity is obvious here, but int he real world it can be much less obvious, and result in some very hard-to-detect bugs.
(Q1) It is important to remember what an include declaration actually does. Basically it is nothing more than a simple copy/paste of the entire file which is being included in the new file.
Since header files are included in many places, it is generally frowned upon to have many unnecessary includes in .h files (unless using templates). In general, do not include in a header file when a forward declaration will suffice.
In the .cpp file, include ALL files necessary so that the program can compile.
Because you are using visual studio, you must be careful because it is very lenient on including files from the standard library that you actually forgot to include, and you may experience problems compiling on other systems.
(Q2) In a header file you should not have a "using" statement. Remember that the include statement is a simple copy/paste; so for that reason if you have a using statement it will be included in the new file as well.
In .h files you should always use std::vector, std::set, etc.
In .cpp files, it is ok to have using namespace std, using std::vector, etc.
(Sidebar) Related to your code, you should split it up into header files and cpp files. Do not have the definition in the .h file, only the declaration. Make a .cpp file and define the algorithm in there. Also do not have define guards in a .cpp file. Never include a .cpp file!
id.cpp
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
public:
static int a;
};
int A::a=20;
class b
{
public:
b()
{
cout<<A::a<<endl;
}
};
int main()
{
b *b1 = new b();
return 0;
}
id1.cpp
#include "stdafx.h"
#include <iostream>
using namespace std;
class c
{
public:
int get()
{
cout<<A::a<<endl;
}
};
int main()
{
c c1;
c1.get();
return 0;
}
This is the way they have declared and got the output in one program but when I'm trying it I'm getting errors as the class is not a namespace or the program id is not included in the id1 file... How to get the variable that is stored in one file into the other file without using namespace and including the header file is there any option for it?
Two separate programs as shown (they're separate because they both define main()) cannot share variables in any simple way.
If the two separate files were to be integrated into a single program, so one of the main() programs was replaced, then you would fall back on the standard techniques of declaring the variable A::a in a header and using that header in both modules. The header would also define class A. This is the only sane way to do it.
You could write the definition of the class twice, once in each file, and declare the variable as an extern in one file and define it in the other, but that is not particularly sensible even in this simple case and rapidly degenerates into unmaintainable disaster if the code gets any more complex and there are more shared variables.
Of course, you might want to consider not using a global variable at all, but provide instead an accessor function. However, you still end up with a header declaring the services provided by the class A and the code implementing those services, and the code consuming those services.