So I was writing, as a small project, a stress test. Initially, to save time, I just plopped code in a header file. I decided to organise it a bit, and moved everything to a .cpp file and then wrote the header file, but VS2010 presented me with an LNK2019 that I can't seem to fix.
FSTRESS.cpp (Didn't include code, because I doubt it is relevant; ask if you need it)
FSTRESS.h
Main.cpp
The error:
error LNK2019: unresolved external symbol "public: static void __cdecl FSTRESS::Start(unsigned int,unsigned int,unsigned int)" (?Start#FSTRESS##SAXIII#Z) referenced in function _main C:\Programming\C++\FLOPS_Test\FSTRESS\FSTRESS\main.obj FSTRESS_Mk.II
Any ideas on why this is happening? I'm a bit of a C++ noob.
Thanks for any help :)
Your .cpp file is not defining the same classes as the ones you've declared in the .h, but creating different classes with the same name as those declared in the header. The correct way to do this is:
Header file:
class Foo
{
void Bar();
};
Implementation file:
void Foo::Bar()
{
// Do something
}
Alternately, you can declare the functions inline in the header file itself
class Foo
{
void Bar()
{
// Do something
}
};
In the latter case there's no need to create a separate implementation file. In fact, this is exactly what you're doing in fstress.cpp, but then you provide a duplicate declaration in fstress.h without actually defining that class anywhere.
So, you've actually got two separate definitions of the x86 and FSTRESS classes, one in the header file and one in the .cpp file. You're allowed to do that provided that the definitions are identical, but they aren't -- the one in the .cpp file has a bunch of inline code, which isn't there in the one in the header file. (Look up "one definition rule" for more information about this.)
What you actually want to do is this. Your header file is fine (or, at least, I don't see anything conspicuously wrong with it). The .cpp file should (1) #include the header file, and then (2) provide definitions for the member functions, looking like this:
static void FSTRESS::Start(unsigned aMode, unsigned aTest, unsigned aThreads) {
// code goes here
}
(When you have a source file and a corresponding header file, the source file should always #include the header file. This helps to make sure that if there's an inconsistency it gets caught tidily at compile time. I can't tell whether you were already doing that because the top of FSTRESS.cpp is invisible in your screen captures. It might have been better to post the code as text :-).)
As an aside, don't use names that begin with an underscore. A large portion of the space of such names is "reserved", meaning that the C++ implementation can use them internally and Bad Things can happen if your use clashes with its use. It's best just to avoid them all, because that way you don't have to remember what the exact rule is and neither does anyone else reading your code.
You can't just paste the contents of the class declaration with inlined code from the header file into the .cpp file and expect it to work. The implementation of FSTRESS::Start() needs to look morel like the following when you separate it from the class declaration:
void FSTRESS::Start(unsigned _aMode, unsigned _aTest, unsigned _aThreads)
{
//...
}
Also, you should #include "FSTRESS.h" in the FSTRESS.cpp file so there's exactly on declaration of the class that everyone uses (include the implementation bits in FSTRESS.cpp).
Related
For C programs, I know I need .h, and .cpp to allow multiple .h to be read and compiled together but linked later.
However, for C++, I don't want to break up the class member function declaration and definition to two parts. Although it is the typical C++ way, I am trying to merge member function declaration and definition in one header file. I saw some people doing that. I would like to know if there is any problem to do this.
I know all members defined in .h class definition are then inline functions, but can they be non-inline in any way? Will compiler be controllable so that they don't have to be inline, for example, when the function is huge?
The VS2015 intellisense shows error when the 2s is in a member function defined in header file, but doesn't show that in cpp file. But it compiles. Is it showing that I am doing it wrong, or it's a bug for VS2015? I deleted the sdf, restarted the project, as long as copy the function into the .h file, it shows a read line under std::this_thread::sleep_for(2s);
see
class testtest {
void tryagain() {
using namespace std::chrono_literals;
auto twosec = 2s;
std::this_thread::sleep_for(2s);// problem is here
}
};
Is compiling faster if we separate the .h and .cpp?
My final compiler would be g++4.9.2, and I am using VS2015 to test build. The final code will run on an ARM with 1GB RAM on Linux.
I don't intend to argue about wich style is better, but hope to focus on whether it works, and what are the trade offs.
It is perfectly fine to place all implementation code in the .h file if you want, it usually depends on the situation. It's usually good practice to split up the interface and implementation even if all the code is in the .h file by doing something like this
class MyClass {
public:
void doSomethingUseful();
};
....
void MyClass::doSomethingUseful() {
// code goes here....
}
Not all functions will automatically be inlined, the compiler usually decides what to inline or not. Larger functions will likely not be inlined even if they're in the header. You can use the inline keyword to give a hint to the compiler that you'd like the function to be inlined but this is no guarantee (also as a small aside, functions marked as inline in a .cpp file will be inlined, but only when called from other functions within that same .cpp file)
Compile times will be slower with more code in the .h file so it's best to try and reduce the amount of code in them as much as possible. I guess in your case though it shouldn't be that noticeable.
I hope that is of some help! :)
You can put defines around functions to prevent them being implemented more than once
header file:-
class MyClass {
public:
void doSomethingUseful();
};
// inline functions
....
// non inline function
#ifdef MYCLASSCPP
void MyClass::doSomethingUseful() {
// code goes here....
}
#endif
Then define MYCLASSCPP in just one CPP file. (or complier parameter).
At the top of a cpp file, I have
namespace PQL {
class Synonym {
...
public:
...
int size();
};
}
// removing the below chunk makes it work
int Synonym::size() {
return ids.size();
}
Why does the bottom chunk make the code fail? I am creating the implementation of the function? Other functions defined a similar way works.
UPDATE:
Expired (dead) link
The error I got looks like:
Error 1 error LNK2005: "public: int __thiscall
PQL::Synonym::size(void)" (?size#Synonym#PQL##QAEHXZ) already defined
in main.obj H:\Dropbox\Sch\CS3202\SPA_CPP\SPA\pql.obj
Because Synonym isn't a name in global scope.
Either use
int PQL::Synonym::size() {
return ids.size();
}
or implement the method inside the namespace.
Its because your code is in a header file and being included in multiple compilation units:
inline int Synonym::size() {
// ^^^^^^^
return ids.size();
}
Adding inline tells the linker that there may be multiple definitions.
Note: The keyword 'inline' has nothing to do with code inline-ing in modern compilers.
As a very important note.
Your header file contains:
using namespace std;
// and
using namespace PQL;
This is a very bad idea. You are now forcing this on anybody that uses your code. I would never use your header file as it would contaminate my code and cause unforeseen problems. It is OK to do this in your own source files (when you know and understand the issues) but you should never force this on other developers.
See: Why is "using namespace std" considered bad practice?
From your comments, I put this together: You put everything in a single Cpp file and include that file in different other files. Each of those files compiles, and each of those files has an implementation of PQL::Synonym::size(). When linking, the linker sees all those definitions and doesn't know which one to choose.
Split your code into header and source files and just include the header in the other files.
i have two files, utility.h and utility.cpp. i declare a struct BoundingSphere in the .h file
struct BoundingSphere
{
BoundingSphere();
D3DXVECTOR3 _center;
float _radius;
};
BoundingSphere::BoundingSphere()
{
_radius = 0;
}
if i put the BoundingSphere::BoundingSphere() implementation into the .h file, i get a link error, error LNK2005: "public: __thiscall BoundingSphere::BoundingSphere(void)" already defined in bounding.obj
but, if i put the implementation into .cpp file, it works ok.
my question is that how it could happen?
This happens because your first code example breaks the One Definition Rule.
When you include the definition in the header file the precompiler merely copy pastes the content of the header in every translation unit where you include the header.
What you end up with is multiple definitions of the same function, this breaks the One Definition rule and hence the linker error.
If you need to add definitions in the header file then you need to mark the function as inline. Though you should note that request to inline a function is merely a suggestion to the compiler and it is free to accept or reject it.
Als tells the truth (not the whole truth, though), but to answer your question: if you put the implementation into .h file, then you have it in object files compiled from each source that includes the header. Therefore, you have multiple definitions. If you put it into .cpp file, then it is defined only once in that file.
I have added some const character in my file as under. The error i get is duplicate symbol _xyz(say). What is the problem with it and how could i get out of this.
const char* xyz = "xyz";
class Abc
{
public:
Abc()
{
}
};
If this is in a header file, you're defining xyz every time you #include it.
You can change the declaration as #R Samuel Klatchko shows. The usual way (if the data isn't const) is like this:
In Abc.h:
extern char *xyz;
In Abc.cpp:
char *xyz = "xyz";
Edited to add
Note that header guards will not solve this problem:
#ifndef XYZ_H
#define XYZ_H
...
#endif
Header guards prevent "redefinition" errors, where the same symbol appears twice in the same compilation unit. That's a compiler error.
But even with header guards the definition of xyz will still appear in every source file that includes it, causing a "duplicate symbol" error, which is a linker error.
It would have been more helpful if the original poster had mentioned that, of course.
The problem is every source file that includes your header file gets it's own copy of xyz with external linkage.
The easiest way to fix that is to give xyz internal linkage. You can do that by making the pointer itself const in addition to having the underlying char's const:
const char* const xyz = "xyz";
I also ran into this issue, but for me the solution was different. I had put overloaded operators (==, !=, <<) in my header file and implemented them. This was causing an issue in other files where I also used ==, !=, or <<. To solve this, I moved the implementation into the .cpp file and left the declaration in the header file.
Edit:
This can also be caused if:
You are including .cpp files instead of .h files. You can fix this by switching the import to use .h instead of .cpp.
You are implementing static functions inside a header file (outside of the class declaration). You can fix this by moving the implementations into a .cpp file (among other solutions).
My use-case:
I had multiple header files a.hpp, b.hpp, and, c.hpp which contained some utility methods.
I had a file util.hpp which acted as an aggregator for the above files.
In my case, the extern did not work but static worked.
I had to use:
header guards to avoid errors in Visual Studio code.
static with functions to avoid compile-time errors.
Check out this article too.
I currently have a program where my main code is in a file main.cpp.
Main.cpp includes a header file "class.h" that declares a class that is used within main.cpp.
Also in main.cpp I have function declarations that declare the functions I use within main.cpp.
The code for these functions is in a separate .cpp file fucntions.cpp.
Like main.cpp, functions.cpp also includes class.h as the class type is used within the functions.
class.h contains the class declaration only.
The implementation code for class.h is in a separate .cpp file classimplementation.cpp.
It all works fine until I try to make the class in class.h a template class.
Then I get linking problems. Research and testing has shown me that this is because the definition of the template class functions needs to reside in class.h with the declaration.
I therefore took the required code out of classimplementations.cpp and put it into class.h.
This did solve my original linking issues but instead I get more linking errors that seem to be telling me I am trying to redefine the functions that I moved to into class.h.
This I think is because class.h is being called by main.cpp and again by functions.cpp.
Therefore the functions in class.h are being defined twice:
Error 41 error LNK2005: "public: __thiscall RecordPocket::RecordPocket(int)" (??0?$RecordPocket#VT####QAE#H#Z) already defined in classimplementation.obj functions.obj
I know that class implementation code should really be kept out of include files but due to the template class limitation of having to keep the class functions local I appear (in my novice mind) to have no choice.
Has anyone been in this scenario and can offer any advice.
I have tried surrounding the functions I moved from classimplementation.cpp to class.h with the standard ifndef CLASSIMP, #define CLASSIMP code and PRAGMA ONCE but neither make any difference.
If all else fails I will move the functions from functions.cpp into main.cpp so that class.h gets called just the once but I’d rather find out what I’m doing wrong as I’m sure it will happen again.
You could keep the template functions inside the template<> class what{/HERE/};
template<typename T>
class MyTempClass{
void myFunctions{
// code here
}
}
EDITED: I removed the code corrected by Glen
I think your problem is revolves around these issues. As you have implied any template function definition (i.e. template function of member function of a template class) needs to be fully expressed in the .h file because when the compiler finds a specific instance of the template it needs to build the function.
You figured this out and moved some implementation into your class.h file. Now if the linker find a MyFunction() in more than one module then is just discards one of them a no linker error is reported.
However you can't define the same non-template function in two different modules as this generates the error you are getting above. So I suspect you also moved some non-template functionality into the .h file; thus including it in two separate obj files and generating the linker error. This theory is support by your quoted error message as I note __thiscall RecordPocket::RecordPocket(int) does not appear to be template.