linking, including argh!!!
Hi!
My situation:
Trying to move my old functions to a new project. Function clamp is defined in basic.h (there's no basic.ccp, its implemented in the h-file, would that matter?) a though that if i do:
#ifndef BASIC_H
#define BASIC_H
//my basic functions declared here (this is the file basic.h)
#endif
It would be ok to include this basic.h in several files. But i got problem when icluding it:
Main.obj : error LNK2005: "void __cdecl clamp(int &,int,int)" (?clamp@@YAXAAHHH@Z) already defined in funcGFX.obj
whats the problem in this scenario? Such things really eat up my time with new projects, and i never learn. I asked this question earlier but it didnt help me understand. My idea is to have like
engine.h
basic.h
function.h
world.h
player.h
etc
Include them all in ONE file, and then include that file in all files. This works in some situation and i cannot really understand when and why. Plz help...
Do you have a funcGFX.cpp and/or funcGFX.h? If you have included basic.h in funcGFX.h and then included funcGFX.h AND BASIC.H in main that might cause the problem.
If that deosnt help, I suggest just removing your includes for basic.h and recompiling to see if u get errors due to its absence that way you can tell where the include is actually being used.
One last thing. Try getting rid of your ifndef/define/endif and just sticking "#pragma once" at the top of basic.h
Posting a list of files and includes within them would be useful I think if none of that works.
All the best,
Hugh Osborne
www.indirectx.co.nr
If that deosnt help, I suggest just removing your includes for basic.h and recompiling to see if u get errors due to its absence that way you can tell where the include is actually being used.
One last thing. Try getting rid of your ifndef/define/endif and just sticking "#pragma once" at the top of basic.h
Posting a list of files and includes within them would be useful I think if none of that works.
All the best,
Hugh Osborne
www.indirectx.co.nr
It really is a very bad idea to have functions implemented in header files, for precisely this reason. If you are using templates it is pretty much unavoidable, but otherwise try to stay away from it.
#ifndef BASIC_H
#define BASIC_H
//my basic functions declared here (this is the file basic.h)
#endif
Those inclusion guards let you make it through the compiler, and ensure that those functions only occur once in each object file. But when the linker tries to link the object files, it finds that each object file has a definition of these functions, and it aborts.
The simplest way to fix this is to move the implementations of these functions into a 'basic.cpp' file.
#ifndef BASIC_H
#define BASIC_H
//my basic functions declared here (this is the file basic.h)
#endif
Those inclusion guards let you make it through the compiler, and ensure that those functions only occur once in each object file. But when the linker tries to link the object files, it finds that each object file has a definition of these functions, and it aborts.
The simplest way to fix this is to move the implementations of these functions into a 'basic.cpp' file.
If you define the function in the header, then include the header in more than one unit, then link the units together, there will be multiple definitions of the function in the final set of .obj files hence the linker error.
There are two solutions:
1) declare the function inline. This is not a good solution for this situation unless the function is a good candidate for being inlined anyway and this is not what inline should be used for
2) define the function in a .cpp file
x.h
x.cpp
main.cpp
As long as you follow that model, you could then have a single header that included x.h, y.h and z.h and so on, and just include that in main.cpp in order to access the functions (although that is questionable from a design point of view).
x.h and x.cpp are compiled seperately into x.obj, main.cpp is compiled into main.obj. At this point the only way they are aware of each other is through x.h. The linker, not the compiler, then takes these two object files and resolves them into an exe.
If "function" was defined in the header file and two units both included the header, they would compile into two objects okay, but both objects would contain their own copy of "function" so the linker will bomb out when it tries to resolve them into an exe.
HTH Paul
There are two solutions:
1) declare the function inline. This is not a good solution for this situation unless the function is a good candidate for being inlined anyway and this is not what inline should be used for
2) define the function in a .cpp file
x.h
#ifndef x_H#define x_Hvoid function(int x);#endif
x.cpp
#include "x.h"void function(int x){ do_stuff(x);}
main.cpp
#include "x.h"int main(){ function(23);}
As long as you follow that model, you could then have a single header that included x.h, y.h and z.h and so on, and just include that in main.cpp in order to access the functions (although that is questionable from a design point of view).
x.h and x.cpp are compiled seperately into x.obj, main.cpp is compiled into main.obj. At this point the only way they are aware of each other is through x.h. The linker, not the compiler, then takes these two object files and resolves them into an exe.
If "function" was defined in the header file and two units both included the header, they would compile into two objects okay, but both objects would contain their own copy of "function" so the linker will bomb out when it tries to resolve them into an exe.
HTH Paul
Sounds like you define the clamp function in the header instead of just declaring the function header.
So you have a header called basic.h which has something like this in it:
Then you have your source files Main.cpp and FuncGFX.cpp, both of which include basic.h. Since including a header is really just telling the compiler system (the preprocessor, to be precise) to cut-and-paste the header into the current file, the function gets created in the .obj's for both files. The linker sees two identical functions with the same name and doesn't know what to do.
To fix this, put the function into a .cpp file instead, and have only the function header in the header file (this is kind of why they got to be called "header files").
The function header is just the "first line" of the function - the function type, name and parameters, followed by a semicolon. No curly braces. What should be in your header file should look something like this:
So you have a header called basic.h which has something like this in it:
void clamp(int & something1,int something2,int something3){/*some code*/}
Then you have your source files Main.cpp and FuncGFX.cpp, both of which include basic.h. Since including a header is really just telling the compiler system (the preprocessor, to be precise) to cut-and-paste the header into the current file, the function gets created in the .obj's for both files. The linker sees two identical functions with the same name and doesn't know what to do.
To fix this, put the function into a .cpp file instead, and have only the function header in the header file (this is kind of why they got to be called "header files").
The function header is just the "first line" of the function - the function type, name and parameters, followed by a semicolon. No curly braces. What should be in your header file should look something like this:
void clamp(int & something1,int something2,int something3);
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement