Link error when adding array to common functions class - c++

I have a common functions class. Basic stuff, just has functions several classes in my project can use. But i am trying to add an array of structs so that several classes can use them for some things. Ive removed this array of structs from another Class (Class 1) and added them to my CommonFunctions class. They are only going to be read.
But Im getting errors:
CommonFunctions.obj : error LNK2005: "struct pup_file * pups" (?pups##3PAUpup_file##A) already defined in Class1.obj
error LNK2005: "struct pup_file * pups" (?pups##3PAUpup_file##A) already defined in Class1.obj
fatal error LNK1169: one or more multiply defined symbols found
Then for every other class in the project (which uses the CommonFunctions class, so all of them really) I get
error LNK2005: "struct pup_file * pups" (?pups##3PAUpup_file##A) already defined in main.obj
Anyone help me with whats going on here?

It looks like you didn't declare the pointer pups (it's not an array) inside the class definition.
If you put it in the header but outside the class, you would get errors like those.
The solution is to make sure that pups is declared inside the CommonFunctions class definition.

After reading your comment on making it a static you probably want to define it as an extern rather than static as static means that everything that includes that definition gets its OWN copy (ie the copy is not shared between all of the files that include it).
Extern means that you will need to define it in a c/cpp file somewhere but you must only define it once and then any compilation unit that includes that extern will use the same structure.
Of course you might actually want each compilation unit to have its own copy of the variable and in which case static is what you want.

Related

What is meant by 'data variable'?

What does 'data variable' mean in MSVS2010 in this error? I thought I was declaring a symbol that is defined elsewhere in my code.
error C2365: 'g_surf' : redefinition; previous definition was 'data variable'
Obviously this could mean an int or char.
I followed a working example.
I had to include a definition of the class before declaring the symbol.
#include classdef.h
I used the extern keyword to declare an object in stdafx.h.
extern COriginal g_orig;//works
extern CClass g_surf;//how is this declaration resulting in a 'data variable' type?
I instantiate a class in a code file (in global space). This is where the error occurs.
COriginal g_orig(CONST_ARGUMENT);//works
CClass g_surf();//seen as redefinition.
I created a class from two other classes because I need attributes from both.
I can find other redefinition questions that do not offer insight to this one. I haven't found in MSVS2010 or on the web what is meant by 'data variable'.
You probably meant to call a constructor with no parameters.
CClass g_surf;
For your compiler, this line
CClass g_surf();
is the forward declaration of a method called g_surf taking no parameters and returning a CClass.
'Data variable' does appear to include symbols declared with class types.
So, I was trying to redefine the type of the symbol to something else.
I was trying to use the same symbol to declare a function.
The mistake I was making in my code was adding parenthesis on the symbol name when instantiating a class.

Unresolved Externals

I am working on a simple top down shooter and wanted to move my ships to a separate ShipManager class, where I can manage all of them from a single location. However, upon starting this I get a linker error on my playerShip:
error LNK2001: unresolved external symbol "public: static class Ship * ShipManager::playerShip"
ShipManager.h looks like this:
class Ship;
class ShipManager
{
public:
static Ship* playerShip;
};
I have nothing in the ShipManager .cpp yet. What am I missing? The only other place I use this code is in my game class where I am actually calling ShipManager::playerShip, and I don't get any errors there.
I include "ShipManager.h" in my game.cpp, so it should find it right? I have a feeling I'm forgetting something simple in this class.
Static members have to be defined somewhere. You are declaring playerShip, but not defining it. You need to add somewhere, necessarily and only one cpp file:
Ship* ShipManager::playerShip;
You only declared the static member, you also need to define it in (only)one of your cpp files:
Ship* ShipManager::playerShip;
Good Read:
What is the difference between a definition and a declaration?

Why error LINK2005: object already defined error disappears when I declare the object as static

I have the follwoing structure and object of structure defined in the header file as below:
struct STConfigurationDetails
{
bool bAutoStart;
bool bAutoLog;
bool bAutoScan;
bool bAutoMount;
bool bAutoOpen;
bool bAutoDetectLast;
};
struct STConfigurationDetails g_objConfigurationDetails ;
In the header file it self I have both method and method body which is using g_objConfigurationDetails . This works fine when I include the header file to another cpp file and call the method. But the moment I added the header file to another cpp file I got the error:
Error 1 error LNK2005: "struct STConfigurationDetails g_objConfigurationDetails" (?g_objConfigurationDetails##3USTConfigurationDetails##A) already defined in NDSClientDlg.obj NDSConnectDlg.obj NDSClient
Error 2 fatal error LNK1169: one or more multiply defined symbols found d:\FromClearCase\Development_view\NDS_11152010\exe\Debug\NDSClient.exe 1 NDSClient
After searching few threads I found out I have to declare my object as static and it solved. But I want to know why was I getting multiple instance error while I was creating the instance only in te header file.
Is this because my Header File has a global variable and it is being included in multiple CPPs?
Adding static might solve your linking problem, but gives you a much bigger problem. That variable is no longer global and has a different value in every CPP file that uses it. You need to declare it as extern in the header file and then declare it one more time in just one CPP file as is.
When you use static it means the variable will be completely local to the current CPP file and will not be exposed to other files. That's why the linker no longer cares if there is another static variable in another file that has the same name. They are not the same variable.
If you want a truly global variable, it must be declared in exactly one CPP file and only its prototype (with extern) should be in a header file that will be shared with other CPP files. It's exactly like functions - declared in one file, prototyped for the rest. For functions, you simply don't provide a body. For variables, you use extern.
This is quite easy if you think of it carefully. The variable is defined in the header so each .cpp file that includes that header gets its own copy of the variable. Now if you don't add static all the .cpp files get the same variable with external linkage and an error occurs at compile-time.
When you add static each .cpp still has its variable unrelated to other variables from the same definition but they no longer have external linkage so the linker doesn't emit an error.
However don't forget that each variable is a separate variable that occupies memory and has overhead for construction/destruction and you will get unexpected behavior if you code expects to have only one variable shared across all .cpp files.
Global static variables have internal linkage.

template class, implementation code causing linking issues

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.

Static Lib Multiple Definition Link Error

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.