Strange Linking error - c++

I'm working on a big c++ project and change code from other people. During this I got a linker error stating that reference VarA is multiple defined. I found the corresponding variable and it had been defined in a cpp file which had directly been included into the project. I tried to convert the source file in a header file and a source file, which doesn't work.
I then tried to move the variable declaration into new separate h/cpp only containing this variable, which looks then like:
h-file (aaa.h)
#ifndef AAA_H
#define AAA_H
#include "classAdefinition.h"
extern ClassA VarA;
#endif
cpp-file (aaa.cpp)
#include "aaa.h"
ClassA VarA;
If I now include aaa.h in the main file, the linker error adds the new created aaa.obj to the error message (e.g. VarA is also defined there) which is exactly what I expected. But when I remove the definition of VarA in the main file I get a linker error staying that VarA is not defined, which is really confusing.
Does anyone have a clue what might be the cause of this behavior?
I'm using VS2008, and the project is created with cmake. Might this cause the problem? E.g. could there be a configuration issue? We also use templates quite often, can this lead to the problem?

In order to remove the multiple defined error which occurs because of multiple cyclic calls I suggest the first and foremost thing that you should do is to edit your header files to include the following macro (whatever it might be in your case) give each file a unique name
#ifndef CAR_HPP
#define CAR_HPP
class Car
{
public:
....
protected:
....
};
#endif

I haven't found the error, but the problem is now avoided because most of the third-party code has been changed and the error does no longer occure.

Related

How to reuse C++ classes from one project to another without copying

I am facing the following problem:
I have a project which contains math classes (.h and .cpp files).
I want to use these classes in a different project (not int he same solution) but I can't.
In the new project I add a path to the include files of my math project. When I try to #include them it works and I can see my classes but upon trying to use them I get "Unresolved external". I haven't created a .dll or a .lib so I really don't know what's causing this.
If you have any suggestions, I`ll appreciate it.
Thank you very much in advance.
When I try to #include them it works and I can see my classes but
upon trying to use them I get "Unresolved external". I haven't created
a .dll or a .lib so I really don't know what's causing this.
That you have not created a library is precisely the reason why you get the error. The compilation units in your new project ("the *.cpp files") include the headers for your classes and make use of the class definitions, but the definitions of the members are missing.
For example, let's say you have a file called "c.h" in your old project:
#ifndef C_H
#define C_H
class C
{
public:
C();
void f();
};
#endif
Some *.cpp file in your new project includes the header and uses the class:
#include "somepath/oldproject/c.h"
void someFunction()
{
C c;
c.f();
}
This compiles fine, but it will cause linker errors, because the definitions of C::C and C::f will be missing.
Now, the clean solution to this is certainly not adding somepath/oldproject/c.cpp from your old project to your new project, although that would fix the linker error, but to employ a library-based approach. Turn your math classes into a library project, let's call it "Math Utils", which produces a *.lib file (as you seem to be on Windows), for example math-utils.lib. Add the library's include and release path to your global include and library paths. Then add the math-utils.lib file to the new project's linker dependencies.
And change the code in your new project to:
#include <math-utils/c.h>
void someFunction()
{
C c;
c.f();
}
Do the same thing in the old project! You will end up with three different projects. Two application projects and one library project, the former two depending on the latter.
Creating your own libraries for the first time can be a bit intimidating, but the benefits are worth the trouble.
See also The Linker Is not a Magical Program.

Why does including the .h also make the .cpp source come along with it?

I'm an experienced programmer, but only in high level languages; I'm doing my first really large project in C++ right now.
I've got two classes, ClassA and ClassB; a ClassA is (among other things) an index of ClassBs, so ClassA needs to know what a ClassB is to build arrays out of it, and a ClassB needs to know what a ClassA is so it can update the index when something changes. Both of these classes are in their own .h & .cpp files.
I figured including each from the other would just cause infinite recursion, so I decided to instead have #include "ClassA.cpp" and #include "ClassB.cpp" at the beginning of main.cpp; but doing this just caused the compiler to warn about multiple definitions of every class and method in those files.
After some experimentation I found out that including ClassA.h and ClassB.h produces the desired behavior - but this doesn't make any sense, I'm only including the prototypes of those classes. Surely the code that actually makes them up never gets mixed in? And yet it does.
What's going on here that I don't understand? Why does including ClassA.h also make the actual code for ClassA show up with it? And why does including ClassA.cpp cause every include of ClassA.h to trigger "multiple definition" errors even though they're in a header shield or whatever it's called?
The missing step is that the definitions in ClassA.cpp and ClassB.cpp will not be seen by the linker unless those files are also compiled at some point. If you did something like this:
g++ main.cpp ClassA.cpp ClassB.cpp
then all references to definitions in ClassA.cpp and ClassB.cpp from main.cpp would be resolved. However, if you only did
g++ main.cpp
then the linker would have no idea where to find the definitions in ClassA.cpp and ClassB.cpp and you would probably get an error.
If you're using an IDE, this detail is hidden from you: the IDE ensures that as long as you add a .cpp file to your "project", it will be compiled into the final binary when you build the project.
This is the way how C++ is designed:
Your classes don't need to now anything more than the prototypes of other classes, so you don't have to include more than the headers.
Why is this so? Well, compilation of an entire application is the combination of two steps: compilation of the code itself and then linking (actually, there is a third step preceding these: pre-processing, but we could consider this one as part of code compilation).
Example function call: It is sufficient (exception: inline functions!) to know that a function with a specific proto type exists. The compiler then can generate all the code necessary to do the function call, except for the actuall address of the function - for which it leaves some kind of place holder.
The linker then combines all code generated during the compilation step to a single unit. As now knowing where every function is located, it can fill their actual addresses into the place holders, wherever they may appear.
C++ code is compiled to *.obj for per .cpp file, and it is the link process make the obj files to an executable.
Never include *.cpp because it usually causes redifinition issue.
For each *.h file, add a macro to avoid multiple including:
#ifndef XXX_H
#define XXX_H
//your code goes here
#endif

C++ multiple definition error when including external library

I'm trying to write a simple application allowing the user to perform a series of symbolic manipulations on a set of linear equations and am using the "Symbolicc++" library (more specifically, the latest version 3.35) for this purpose.
Since I don't have much experience with C++ and have never actually used a third-party library before, it's quite possible that I simply don't know how to properly use a library and am making some stupid mistake.
The problem is that I get a lot of multiple definition errors when I try to compile (and link) any program consisting of more than one file that includes the library's main header; the errors refer to functions and classes that are defined in the library's files (not mine).
A very simplistic example: suppose we have the files main.cpp, head.h and head.cpp. The contents is as follows:
main.cpp
------------------
#include <iostream>
#include "head.h"
int main()
{
return 0;
}
head.h
------------------
#ifndef SOMETHING
#define SOMETHING
#include "symbolicc++.h"
#endif
head.cpp
------------------
#include "head.h"
//nothing
Of course, the files in the real program contain a lot more, but even with just this, trying to build the program with, e.g.:
g++ -I /path to library's header files/ main.cpp head.cpp
yields hundreds of error message along the likes of:
/tmp/ccYNzlEF.o: In function `Cloning::Cloning()':
head.cpp:(.text+0x0): multiple definition of `Cloning::Cloning()'
/tmp/ccNWUnnC.o:main.cpp:(.text+0x0): first defined here
where, e.g., Cloning::Cloning() is declared in cloning.h, which is one of the library's header files.
A program containing only a single file including symbolicc++.h works just fine.
I also tried building this project on Visual Studio 2012 and got a similar result.
Unfortunately, I wasn't able to find any information about this problem, as virtually all the materials I found concerned errors in header files created by the user (as opposed to libraries created by someone else), so any help would be appreciated.
This library seems seriously broken. The way it is designed, you cannot include "symbolicc++.h" multiple times without violating the one-definition rule.
For example, let's have a look at cloning.h. It defines a Cloning class with a default constructor declaration:
class Cloning
{
private: int refcount;
void (*free_p)(Cloning*);
// ...
public: Cloning();
// ...
};
Later on, within the header file, it also defines that constructor:
Cloning::Cloning() : refcount(0), free_p(0) {}
That's it. Every one of your *.cpp files which directly or indirectly includes cloning.h will be exposed to the definition of the same function. The linker notices the multiple definitions and gives up.
Try to modify cloning.h. Remove the constructor definition line above and place the constructor definition into the class definition, making it an inline function:
// just to see what's going on...
class Cloning
{
private: int refcount;
void (*free_p)(Cloning*);
// ...
public: Cloning() : refcount(0), free_p(0) {};
// ...
};
This will fix the error for Cloning::Cloning. But that's just to shed more light on the issue; I don't advise you to do this. It would be the library authors' job to fix their code.
Further recommended reading: Why include guards do not prevent multiple function definitions?
Here is a way for you to reproduce the same problem with a few lines of your own code:
head.h:
#ifndef SOMETHING
#define SOMETHING
struct Example
{
Example(); // constructor declaration
};
Example::Example() // constructor definition
{
}
#endif
head.cpp:
#include "head.h"
//nothing
main.cpp:
#include "head.h"
int main()
{
}
Example linker error (taken from Visual C++ 2013):
1>main.obj : error LNK2005: "public: __thiscall Example::Example(void)" (??0Example##QAE#XZ) already defined in head.obj
1>[...] fatal error LNK1169: one or more multiply defined symbols found
If you absolutely must use this library, you'll have to build your own safe wrapper around it. But frankly, just don't. I'm sure there are numerous other libraries that solve the same problems and that can actually be used according to C++ language rules and conventions.

Error C2011: 'XX' : 'class' type redefinition

I have this compiler error (C2011) with this piece of code. I don't know what is wrong with it.
The namespace (Ogre) doesn't have a definition for PlaneMovement. I also tried a different name and still the same errors.
#include <Ogre.h>
using namespace Ogre;
class PlaneMovement
{
public:
PlaneMovement(Degree startingAngle, Real velocity = 2, Real gravity = 2);
Vector2 updateMovement(const FrameEvent& evt);
private:
Degree currentAngle;
Real currentVelocityX;
Real currentVelocityY;
Real gravity;
bool top;
};
Include guards:
#ifndef FILE_H
#define FILE_H
//file contents here
#endif
Header files should have include guards for this exact reason - multiple inclusion in the same translation unit can lead to a multiple definition.
The alternative is using
#pragma once
but this isn't supported by all compilers.
If someone else faces this situation, it may be when library includes in property of project and header files from this library include in projects file.
Incorrect Forward Declaration
Another possible cause, if you're a goof like me, could be that you used enum instead of class when forward declaring a class.
File1.h
namespace MyNamespace { enum NotActuallyAnEnum; }
File2.h
class NotActuallyAnEnum
{
...
}
This will produce something like the following error:
error C2011: 'enum' type redefinition
Obviously the fix is to correct the forward declaration:
namespace MyNamespace { class NotActuallyAnEnum; }
You might also get this error if you have multiple branches of your project on your development station and use a symlink to point to one of them.
Let's suppose you have two different branches of your solution called Project1 and Project2 and you let a symlink called Project point to either Project1 or Project2.
The idea is that you could switch between branches and the project would always appear to be Project to your application and possibly some other tools that expect it there.
Disclaimer: yes, version control can switch between branches, but this way you will not have to rebuild the whole application every single time you switch branches. Besides both branches can still be under version control.
Okay, so opening Project would open either Project1 or Project2 depending on the symlink. The symlink could be removed/created by some simple mklink_1 and mklink_2 like script files.
Here comes the pitfall:
If you don't pay attention and directly open the solution at location 1 or 2 directly (instead of following the directory symlink with Visual Studio), the pre-processor might be tricked into mixing Project1\MyHeader.h (or MyProject2\MyHeader.h) with MyProject\MyHeader.h!
Even those are technically the same file, the preprocessor doesn't know about the symlink. So here the #pragma once would not save you!

#include, error LNK2005

Alirhgt, i tried to sort this one out myslef but can't. So, i have a task to build a paint program in the console, i have a set of functions dealing with the console. My task being only to connect them logically to do something useful. The problem is that everytime i #include the two files given : the .h and the .cpp file, i get the LNK2005 error that they are already defined. If i only include the header file, the functions don't do anything( i tried using one function but the console just stood there doing nothing). Can anybody tell me what i'm doing wrong? I haven't worked with C++ in a bit, so i might be doing some stupid mistake.
First off, you should never include cpp files.
Second, you might need include guards.
Format headers like this:
#ifndef FILE_H
#define FILE_H
struct foo {
int member;
};
#endif
You can read about why from here: http://en.wikipedia.org/wiki/Include_guard