When I try to build my application the linker gives loads of errors like this one:
modlauch.obj : error LNK2005: "public:
virtual __thiscall
lolbutton::~lolbutton(void)"
(??1lolbutton##UAE#XZ) already defined
in lolbutton.obj
I suspect it has something to do with misconfigured compiler but I don't know how to fix it. My class is only included once so I don't think it has anything to do with the code. I have tried rebuilding and cleaning the project but it didn't help.
Can someone suggest a solution to this problem? My platform is Win32(C++) and I'm using MFC.
You'll get the linker error when you wrote the class like this:
lolbutton.h:
class lolbutton {
public:
virtual ~lolbutton();
};
lolbutton::~lolbutton() {
// something...
}
You won't get it when you write it like this:
class lolbutton {
public:
virtual ~lolbutton()
{
// inlined something...
}
};
Fix the linker error by moving the destructor definition from the .h file to a .cpp file. This ensures there is only one definition of the destructor.
do you by any chance include your lolbutton.h file more than once? like so:
//file: something.h
#include <lolbutton.h>
//... do code
//file: something_other.h
#include <lolbutton.h>
//file: main.cpp
#include <something.h>
#include <something_other.h>
At a guess - without seeing the code - did you by any chance put the destructor for lolbutton in the header without declaring it inline? From your description this is the likely culprit if you end up with instances of the destructor in multiple translation units.
I would go with either multiple includes of lolbutton.h, hence my comment about wrapping the contents in an "if !defined someUUID" block or perhaps it could be to do with the use of precompiled headers.
Related
I'm fairly new to c++, and I'm using this project as a learning experience. I'm working in Visual Studio 2019, and I'm using this library
https://github.com/Arash-codedev/openGA
to try to solve a version of the vehicle routing problem.
I've run into a problem when refactoring my code into separate classes once it got unwieldy including everything in a single cpp file, although a single file was the approach outlined in the OpenGA library's examples.
Currently the bare bones structure that seems to be causing the problem is as follows.
Algorithm.cpp
#include "Crossover.h"
#include "EvaluateSolution.h"
...
Crossover.h
#include "GeneticStructs.h
...
EvaluateSolution.h
#include GeneticStructs.h
...
GeneticStructs.h
#include openga.hpp
...
The external library has the following definition:
openga.hpp
...
std::mutex mtx_rand;
...
GeneticStructs just has Chromosome and Gene structs with overloaded ostream operators for each.
The problem is when I compile, I get the following linker errors:
Crossover.obj : error LNK2005: "class std::mutex EA::mtx_rand" (?mtx_rand#EA##3Vmutex#std##A) already defined in Algorithm.obj
EvaluateSolution.obj : error LNK2005: "class std::mutex EA::mtx_rand" (?mtx_rand#EA##3Vmutex#std##A) already defined in Algorithm.obj
GeneticStructs.obj : error LNK2005: "class std::mutex EA::mtx_rand" (?mtx_rand#EA##3Vmutex#std##A) already defined in Algorithm.obj
So from what I understand, I'm violating the one definition rule. I think I understand why. The mutex gets defined separately in each object file and results in ambiguity when the linker tries to combine the object files. Of course, exposition on what is actually wrong would be welcome, since I'm a newbie to c++.
What would be the proper way to resolve something like this? I think the context should be clear from the outline I've given, but if more is necessary please let me know! Thank you.
This is not your fault; it looks like a bug in that OpenGA library.
The normal way would be to declare the variable in the header as:
extern std::mutex mtx_rand;
Then have one (and only one) source file (e.g. OpenGA.cpp) in which it's defined, taking the namespace into account:
#include "OpenGA.hpp"
NS_EA_BEGIN
std::mutex mtx_rand;
NS_EA_END
Of course, this is not needed if the header is included in one (and only one) source file, which is presumably the way the library's author has been using it.
Since the mutex is only used to protect the std::mt19937_64 rng inside the Genetic template, it might also work to just move the mutex declaration into that template as well. I haven't checked if that would break anything, though.
Thank you very much for using openGA.
This issue has been currently fixed. Please include the openGA in this way:
source1.cpp
#include "openGA.hpp"
...
source2.cpp
#define OPENGA_EXTERN_LOCAL_VARS
#include "openGA.hpp"
...
source3.cpp
#define OPENGA_EXTERN_LOCAL_VARS
#include "openGA.hpp"
...
Except for only one source file, at the beginning of all other source files that use openGA, define macro OPENGA_EXTERN_LOCAL_VARS. Then, you should not get such a linker error.
The mechanism of fix works as follows
#ifdef OPENGA_EXTERN_LOCAL_VARS
extern std::mutex mtx_rand;
#else
std::mutex mtx_rand;
#endif
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.
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).
It's a well known issue this damn error
expected class-name before ‘{’ token
Well, despite my hard working and googling, I could not solve this error. Sorry. This is my last shore.
In ui.cpp of a project of mine I do:
#include "wfqueue_proxy_factory.hpp"
OK, this raises this stupid error in my compiler:
In file included from
wfqueue_proxy_factory.hpp:29,from
ui.cpp:28:
wfqueue_manager_proxy.hpp:42: error:
expected class-name before ‘{’ token
There are three classes in my project:
First
// wfqueue_proxy_factory.hpp
#ifndef _WFQUEUE_PROXY_FACTORY_HPP
#define _WFQUEUE_PROXY_FACTORY_HPP
#include "wfqueue_manager_proxy.hpp"
// ...
class WFQueueProxyFactory {
//...
};
#endif
Second
// wfqueue_manager_proxy.hpp
#ifndef _WFQUEUE_MANAGER_PROXY_HPP
#define _WFQUEUE_MANAGER_PROXY_HPP
#include "workflow.hpp"
#include "wfqueue.hpp"
// ...
class WFQueueManagerProxy : public WFQueue { // This is the problem (line 42)
//...
};
#endif
Third
// wfqueue.hpp
#ifndef _WFQUEUE_HPP
#define _WFQUEUE_HPP
#include "workflow.hpp"
class WFQueue {
// ...
};
#endif
PLEASE PLEASE PLEASE note that I use ; after } of every class, I checked out EVERY header in my project looking for this problem and didn't find any class not followed by ; after its closing bracket. This is valid for workflow.hpp which is a simple class (not deriving from any class, just a plain class).
WFQueue is some sort if interface, I use this pattern with other classes too and they work. WFQueue contains some virtual pure methods... problem should not be here anyway.... I suppose this because I use another "interface" class with other classes and they work fine.
This error disappears if I do this:
// wfqueue_manager_proxy.hpp
#ifndef _WFQUEUE_MANAGER_PROXY_HPP
#define _WFQUEUE_MANAGER_PROXY_HPP
#include "workflow.hpp"
#include "wfqueue.hpp"
// ...
class WFQueueManagerProxy {
//...
};
#endif
Don't really know how to solve this problem... please help me.
Thank you
You should run the preprocessor on your code but not compile it, and examine the result. To do this, copy the command which runs the failing compilation, and with most compilers you'd then remove the -o outfile option and add something like -E (see your compiler's documentation for the flag which does preprocessing only).
The compiler will emit (on stdout) the entire translation unit with all #includes and such resolved, so you can clearly see what is missing (just search for the line of code that matches the error line, then look up to see what declarations you find). If it's still not clear what the problem is, write the preprocessed output to a file and try compiling that. You can then tweak the preprocessed source and see what's needed to fix it.
Just a wild guess: Your error says that in
class WFQueueManagerProxy : public WFQueue { // This is the problem (line 42)
//...
};
there must be a class name before {. Therefore I assume that the compiler doesn't know that WFQueue is a class. Are you sure that its definition is included? I mean, maybe in wfqueue.hpp the class is named WfQueue or different in some other way?
The problem might be in misnamed include guards. Try to check if they are really unique per file. It seems that you made it to disable the definition of WFQueue while compiling WFQueueManagerProxy.
It's something it never happened... my god sorry...
It seems that my virtual machine backup disk collided with the original one. I run my project on a virtual machine, making the backup, 2 hours ago, probably messed up something... I adjusted it and now the virtual machine can locate the correct folder and the correct files to compile. It was amazing ahaha and obvious, the ols files g++ tried to compile where a previous version filled with mistakes... This was one of that bugs... a guard header repeated.
Icecrime was right... despite I looked for repetitions in my files, in the previous version, where I didn't fix this problem, there were some files I pasted and forgot to change guard header.
Thank you everyone for your patience and effort.
I'm sorry I didn't notice this very strange virtual disk collision in my machine. Thanks again.
Make sure you typed
using namespace omnetpp;
after includes. It solved my problem.
So I'm trying to build a small 3D engine as an exercise on VC++ 8.0. I have a MathLib static lib and a Render static lib that is being linked by my TestBed exe. Right now Render has two classes: Color and DXManager3D. Color includes my Vector.h from MathLib just fine, no problems.
The second I try to include Vector.h in DXManager3D it blows up on me, saying the symbol is defined twice, and the second definition is ignored (warning from lib). I thought maybe including it twice was causing this so as a test I removed Vector.h from Color.h and left it in DXManager3D.h - same problem. I have triple checked to make sure I have everything wrapped in ifndef to protect from this, so I am left scratching my head.
DXManager3D.obj : warning LNK4006: "public: __thiscall Math::Vector::Vector(void)" (??0Vector#Math##QAE#XZ) already defined in Render.obj; second definition ignored
What really confuses me is that when I build the Render.lib separate from TestBed, which should not be linking anything as it is a static lib, right? I still get the multiple symbol definition warnings. If I instantiate a DXManager3D in main my warnings become errors.
Render.lib(DXManager3D.obj) : error LNK2005: "public: __thiscall Math::Vector::Vector(void)" (??0Vector#Math##QAE#XZ) already defined in WinMain.obj
Yes, I have F1'd LNK4006 and LNK2005 and the solutions in the MSDN aren't working for me.
Sorry if this question has been asked before, I couldn't find anything solid to help me out using the search feature.
Thanks!
Is your Vector ctor defined in the header outside the class definition? Make it inline then i.e. change
class Vector {
public:
Vector();
// ...
};
Vector::Vector() {
// ...
}
to
class Vector {
public:
Vector() {}
// ...
};
or use an explicit inline qualification:
class Vector {
public:
Vector();
// ...
};
inline Vector::Vector() {
// ...
}
It looks like you have a linkage issue with your vector class. Based on your information it appears that the class is being linked into any lib which includes the header file. This is internal linkage, and you really want external linkage.
Can you post the contents of Vector.h, or at least the Vector() constructor? That should give us a clue to what is actually going on.
Linkage: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/cplr020.htm
EDIT
Based on your comment, it appears that you have declared all of the functions in the header file outside the class library. You should put them into a non-header file (Vector.cpp file for instance).
This will give your program the appropriate linkage and you will be able to include Vector.h in both programs.