The VC++ compiler can incorperate multiple .cpp files into one program, along with libraries. It does this by converting all of the .CPP files into a specially formated bank of assembler (machine) code called an Object File (.OBJ). If you define the same symbol (variable, function, structure, etc.) in more than one .CPP file or library (.LIB, usually) then the linker (which incorperates the .OBJs and .LIBs into one .EXE) will give errors as the one above.
Now that you understand the nature of the problem, here's how you fix it:
First, if you're using custom-made header files, make sure that you're not defining the same variables twice:
--- File HEADER1.H ---
vector<int> v_nNums;
void InitNums();
void InitNums();
--- File CODE1.CPP ---
#include <vector>
#include <iostream>
using namespace std;
#include <iostream>
using namespace std;
#include "HEADER1.h"
int main(){
InitNums();
for(int n = 0; n < v_nNums.size(); n++){
cout<<v_nNums[n]<<endl;
}
for(int n = 0; n < v_nNums.size(); n++){
cout<<v_nNums[n]<<endl;
}
return 0;
}
}
--- File CODE2.CPP ---
#include <vector>
using namespace std;
using namespace std;
void InitNums(){
v_nNums.push_back(5);
v_nNums.push_back(3);
v_nNums.push_back(3);
}
---
This simple example *should* print 5 and 3 on seperate lines, right? But the problem is, you've declared the same variable, 'vector<int> v_nNums', twice. This is because EACH of the .CPP files includes the header, and every time the header is included, you declare the variable. This will cause a linker error as the one you recieved above.
In order to make a variable visible to multiple seperate .CPP files, you need to use the 'extern' keyword. 'extern' is to a variable as a prototype is to a function: It's basically an IOU. This way, you can tell the compiler that the variable exists, and what it is, without declaring it. (Much like you can give the compiler an IOU on functions by defining thier prototypes.) You then need to declare the variable without the 'extern' keyword in ONE and ONLY ONE of the .CPP files.
The code from above SHOULD be changed as follows:
In HEADER1.h, add the 'extern' keyword to the vector's declaration:
--- File HEADER1.H ---
extern vector<int> v_nNums;
void InitNums();
void InitNums();
--------------------------
In either CODE1.cpp *OR* CODE2.cpp, add this line, somewhere after the headers, and not inside a function or class (global scope):
--- File CODE1.CPP ---
#include <vector>
#include <iostream>
using namespace std;
#include <iostream>
using namespace std;
#include "HEADER1.h"
vector<int> v_nNums;
int main(){
InitNums();
/* Rest of code truncated to shorten post*/
---
---
This should enable you to debug your code.
If you're using a premade header, it's a bad one. You could try to repair it yourself, or find another tutorial. I gather you're using D3D... there's plenty of stuff out there.
Oh, two more points:
Personally, I find it helpful to create a .CPP file with the same name as the header file, in this case, HEADER1.CPP, and store all of it's variables there. This saves a lot of time an confusion, esp. on projects longer than 1000 lines.
Second, you can also get this link error if you define a function body in a header file. I can see that's not the case here, but it might come up for people searching this forum. You should always PROTOTYPE functions in headers, NOT define them. For example:
void InitNums();
was a prototype, whereas
void InitNums(){
v_nNums.push_back(5);
v_nNums.push_back(3);
v_nNums.push_back(3);
}
was a definition. Do the same as above, prototype in headers, and define the function bodies (the code itself) in a .CPP file.
IN SUMMARY:
- Never define variables in headers, always use the 'extern' keyword and define the variable in one and only one CPP file.
- Never define function bodies in header files. Use prototyping, by replacing the brace brackets that contain the code with a single semicolon (';') and then define the function body (the code with brace brackets) in one and only one CPP file.
- Header files are not for code! They are for making CPP files work with each other and libraries only!
I hope that helps you. If you have any trouble with this, feel free to e-mail me, remembering to look carefully at my e-mail address and remove the part after the hyphen (I don't want a load of spam today, thanks.)
Good luck, and happy coding!
-Dave S.
****************************************************************************************************************************************************************
Source: http://www.gamedev.net/topic/127451-one-or-more-multiply-defined-symbols-found/
Each translation unit including your "MemberList.h" header gets a copy of the members, listOfMembers, numOfMembers and sizeOfListvariables.
This is fine for the later two which are declared static, which means that the numOfMembers variable that MemberList.c sees isn''t the same variable as that which main.c sees (which is probably not what you want).
However, for the former two, the linker sees two symbols (here, variables, but could be functions) with the same name in two separate object modules and aborts, reporting the name collision.
The solution is to declare the variable extern in the header file (which is similar to having a function prototype) and to define it in a single source file (similar to having a function body).
See the ''Header file'' link in my signature.
****************************************************************************************************************************************************************
Source: http://www.gamedev.net/topic/127451-one-or-more-multiply-defined-symbols-found/
Each translation unit including your "MemberList.h" header gets a copy of the members, listOfMembers, numOfMembers and sizeOfListvariables.
This is fine for the later two which are declared static, which means that the numOfMembers variable that MemberList.c sees isn''t the same variable as that which main.c sees (which is probably not what you want).
However, for the former two, the linker sees two symbols (here, variables, but could be functions) with the same name in two separate object modules and aborts, reporting the name collision.
The solution is to declare the variable extern in the header file (which is similar to having a function prototype) and to define it in a single source file (similar to having a function body).
See the ''Header file'' link in my signature.
0 comments:
Post a Comment