linking, including argh!!!

Started by
6 comments, last by Kylotan 17 years, 7 months ago
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...
Advertisement
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
--------------------------------www.hughosborne.co.uk[email=hugh.osborne@googlemail.com]hugh.osborne@googlemail.com[/email]
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.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

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
#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:

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);
thanks a bunch

ill try to clean up everything, separate headers and implimentation and see if it helpes.

e
Here is a great article that explains all of this: Organizing Code Files in C and C++.
It's a fantastic article and the author should be sent gifts of money and women. ;)

This topic is closed to new replies.

Advertisement