i have two files, utility.h and utility.cpp. i declare a struct BoundingSphere in the .h file
struct BoundingSphere
{
BoundingSphere();
D3DXVECTOR3 _center;
float _radius;
};
BoundingSphere::BoundingSphere()
{
_radius = 0;
}
if i put the BoundingSphere::BoundingSphere() implementation into the .h file, i get a link error, error LNK2005: "public: __thiscall BoundingSphere::BoundingSphere(void)" already defined in bounding.obj
but, if i put the implementation into .cpp file, it works ok.
my question is that how it could happen?
This happens because your first code example breaks the One Definition Rule.
When you include the definition in the header file the precompiler merely copy pastes the content of the header in every translation unit where you include the header.
What you end up with is multiple definitions of the same function, this breaks the One Definition rule and hence the linker error.
If you need to add definitions in the header file then you need to mark the function as inline. Though you should note that request to inline a function is merely a suggestion to the compiler and it is free to accept or reject it.
Als tells the truth (not the whole truth, though), but to answer your question: if you put the implementation into .h file, then you have it in object files compiled from each source that includes the header. Therefore, you have multiple definitions. If you put it into .cpp file, then it is defined only once in that file.
Related
I have a header file which begins with
#if !defined(__GLOBAL_H)
#define __GLOBAL_H
then some code followed by
#endif
The code contains only function declarations, some include of other header files and the a few template functions. However, the problem occurs when I add one single line of code. I get linker error that the function I added has already been defined in an object file. I'm using Visual Studio 2012 Premium as compiler. I have tried to remove any existing function from the header file, and that also goes through the compiler. On the other hand, if I add any new line that may be new to the compiler, it refuses to compile saying it has already been defined. Does anyone have any clue what might be wrong or can I have stumbled upon an error inside the compiler itself? (which I highly doubt)
Edit:
The solution was to declare the function the the header file, but to define it in the CPP file. But the real issue was that when I include a header file for returning an object of the type declared in the header file, it does not compile. It many of the errors "Missing ; in front of *" which was types declared in other header files.
Although you haven't shown use any code or error messages, I'm guessing that there are function definitions (including the code for the function body), not just declarations, in the header.
These must either be declared inline, which allows them to be defined in more than one translation unit; or moved into a single source file, leaving just the declaration in the header, so they are only defined on one translation unit.
The "One Definition Rule" says that (unless they are inline) functions may only have one definition in the program.
Also, your include guard shouldn't begin with an underscore, nor contain a double underscore; names like that are reserved.
Adding non-inlined function definitions to header files is generally bad. The compiler will generate code for the function in every file it is included in resulting in the redefintion error you are encountering. Instead you should declare the function in the header and place the definition in a source file (.cpp).
Global.h
#if !defined(__GLOBAL_H)
#define __GLOBAL_H
void somefunction(); // <-- declaring the function.
#endif
SomeSource.cpp
#include "Global.h"
// Here is where define the function
void somefunction()
{
}
I'm new to using header files and such, last semester we did everything in one giant(horrible :p) file ...
Am I doing something I'm not supposed to? Attempting to run the program results in the following:
1> LINK : ~~~\CSC 161\Accounting Assignment\Debug\Accounting Assignment.exe not found or not built by the last incremental link; performing full link
1>driver.obj : error LNK2005: "class std::basic_ifstream<char,struct std::char_traits<char> > welcomeFile" (?welcomeFile##3V?$basic_ifstream#DU?$char_traits#D#std###std##A) already defined in statistics.obj
1>~~~~\CSC 161\Accounting Assignment\Debug\Accounting Assignment.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
statistics.h:
#ifndef _STATISTICS_INTERFACE_
#define _STATISTICS_INTERFACE_
...
#include<fstream>
using namespace std;
ifstream welcomeFile; //if I comment this out, it compiles
class Stats
{
...blah...
};
void welcome();
void pause();
void printFile(ifstream &inFile);
#endif
statistics.cpp:
#include "statistics.h"
...working functions...
void welcome()
{
system("CLS");
welcomeFile.open("about.txt");
printFile(welcomeFile);
welcomeFile.close();
pause();
}
The errors look like something is trying to be defined twice, but I thought #ifndef was supposed to set it so it only defined things if they weren't already? This is the only place where I declared welcomeFile ...
Because you defined the object in the header file and violated one definition rule.
Never define objects in header file!
Header guards prevent the contents of the header to be included multiple times in the same translation unit during preprocessing. They do not prevent the contents to be included in different translation units. When you include this header file in different translation units, each of these units will have a definition of this object.
The compiler compiles each translation unit separately to produce a separate object file(.o), each of those .o files will have an copy of this object definition. When the linker tries to link to the object/symbol name at time of generating the .exe it finds multiple definitions of the same object/symbol, thereby causing confusion as to which one to link to. To avoid this problem the standard defines a rule known as the One defintion rule(ODR), which forbids multiple definitions of the same entity.
As you see including the object definition in the header file and including that header file in multiple translation units violates the ODR.
If you want to use a global object, You need to declare it as extern and define it in one and only one source file.
Good Read:
error LNK2005, already defined?
You should put that definition in a .cpp file. Otherwise, every file that includes this .h file will have a definition of this variable, which ultimately clash during linking.
p.s. putting using namespace std; in your header, is considered bad.
So I was writing, as a small project, a stress test. Initially, to save time, I just plopped code in a header file. I decided to organise it a bit, and moved everything to a .cpp file and then wrote the header file, but VS2010 presented me with an LNK2019 that I can't seem to fix.
FSTRESS.cpp (Didn't include code, because I doubt it is relevant; ask if you need it)
FSTRESS.h
Main.cpp
The error:
error LNK2019: unresolved external symbol "public: static void __cdecl FSTRESS::Start(unsigned int,unsigned int,unsigned int)" (?Start#FSTRESS##SAXIII#Z) referenced in function _main C:\Programming\C++\FLOPS_Test\FSTRESS\FSTRESS\main.obj FSTRESS_Mk.II
Any ideas on why this is happening? I'm a bit of a C++ noob.
Thanks for any help :)
Your .cpp file is not defining the same classes as the ones you've declared in the .h, but creating different classes with the same name as those declared in the header. The correct way to do this is:
Header file:
class Foo
{
void Bar();
};
Implementation file:
void Foo::Bar()
{
// Do something
}
Alternately, you can declare the functions inline in the header file itself
class Foo
{
void Bar()
{
// Do something
}
};
In the latter case there's no need to create a separate implementation file. In fact, this is exactly what you're doing in fstress.cpp, but then you provide a duplicate declaration in fstress.h without actually defining that class anywhere.
So, you've actually got two separate definitions of the x86 and FSTRESS classes, one in the header file and one in the .cpp file. You're allowed to do that provided that the definitions are identical, but they aren't -- the one in the .cpp file has a bunch of inline code, which isn't there in the one in the header file. (Look up "one definition rule" for more information about this.)
What you actually want to do is this. Your header file is fine (or, at least, I don't see anything conspicuously wrong with it). The .cpp file should (1) #include the header file, and then (2) provide definitions for the member functions, looking like this:
static void FSTRESS::Start(unsigned aMode, unsigned aTest, unsigned aThreads) {
// code goes here
}
(When you have a source file and a corresponding header file, the source file should always #include the header file. This helps to make sure that if there's an inconsistency it gets caught tidily at compile time. I can't tell whether you were already doing that because the top of FSTRESS.cpp is invisible in your screen captures. It might have been better to post the code as text :-).)
As an aside, don't use names that begin with an underscore. A large portion of the space of such names is "reserved", meaning that the C++ implementation can use them internally and Bad Things can happen if your use clashes with its use. It's best just to avoid them all, because that way you don't have to remember what the exact rule is and neither does anyone else reading your code.
You can't just paste the contents of the class declaration with inlined code from the header file into the .cpp file and expect it to work. The implementation of FSTRESS::Start() needs to look morel like the following when you separate it from the class declaration:
void FSTRESS::Start(unsigned _aMode, unsigned _aTest, unsigned _aThreads)
{
//...
}
Also, you should #include "FSTRESS.h" in the FSTRESS.cpp file so there's exactly on declaration of the class that everyone uses (include the implementation bits in FSTRESS.cpp).
I have C++ project which consists of multiple (in fact many) .cpp and .h files. While writing header files i have a file as follows
For eg MyHeaderFile.h
#ifndef _MYHEARDERFILE_H
#define _MYHEARDERFILE_H
// Here i have function defintion.
void myFunc() {cout << "my function" << endl; }
#endif
Above file is included in multiple files. While compiling i have getting "multiple definition of "myfunc" error.
I am expecting the header is included only once as i have #ifndef check so i am expecting error should not be thrown.
For example in case of templates we have to define in header file, in this case how we can avoid the problem i am facing now?
Can any one please help me why i am seeing the error? is my understanding right?
Thanks!
Normally, one puts function declarations in header files, and function definitions (i.e. the actual function body/implementation) in source files. Otherwise, you get exactly the issue you're seeing: the header file is #included (i.e. substituted) into multiple source files, so the function ends up being defined multiple times. This confuses the linker, so it complains.
The header-guard #ifndef ... stuff only prevents a header from being substituted into the same source file multiple times. Remember that each source file is compiled completely independently from all the others; all #defines and other definitions are "reset" for each one.
One possible alternative solution is to leave the function definition in the header file, but simply to mark it inline (this has the side-effect of eliminating the linker error). But, personally, I wouldn't do that.
Every function must be defined only once in a single translation unit (this is called One definition rule, and applies not only to functions). By placing the definition in a header which is then included, you are violating this rule.
You can simply leave the declaration
void myFunc();
in the header, and define myFunc in a .cpp which provides the definition.
Otherwise you can declare your function inline.
Note that when using templates, instead, you are usually led (for template-related specific issues) to place definitions directly in the headers, which could appear surprising given the problems you are facing now.
I have added some const character in my file as under. The error i get is duplicate symbol _xyz(say). What is the problem with it and how could i get out of this.
const char* xyz = "xyz";
class Abc
{
public:
Abc()
{
}
};
If this is in a header file, you're defining xyz every time you #include it.
You can change the declaration as #R Samuel Klatchko shows. The usual way (if the data isn't const) is like this:
In Abc.h:
extern char *xyz;
In Abc.cpp:
char *xyz = "xyz";
Edited to add
Note that header guards will not solve this problem:
#ifndef XYZ_H
#define XYZ_H
...
#endif
Header guards prevent "redefinition" errors, where the same symbol appears twice in the same compilation unit. That's a compiler error.
But even with header guards the definition of xyz will still appear in every source file that includes it, causing a "duplicate symbol" error, which is a linker error.
It would have been more helpful if the original poster had mentioned that, of course.
The problem is every source file that includes your header file gets it's own copy of xyz with external linkage.
The easiest way to fix that is to give xyz internal linkage. You can do that by making the pointer itself const in addition to having the underlying char's const:
const char* const xyz = "xyz";
I also ran into this issue, but for me the solution was different. I had put overloaded operators (==, !=, <<) in my header file and implemented them. This was causing an issue in other files where I also used ==, !=, or <<. To solve this, I moved the implementation into the .cpp file and left the declaration in the header file.
Edit:
This can also be caused if:
You are including .cpp files instead of .h files. You can fix this by switching the import to use .h instead of .cpp.
You are implementing static functions inside a header file (outside of the class declaration). You can fix this by moving the implementations into a .cpp file (among other solutions).
My use-case:
I had multiple header files a.hpp, b.hpp, and, c.hpp which contained some utility methods.
I had a file util.hpp which acted as an aggregator for the above files.
In my case, the extern did not work but static worked.
I had to use:
header guards to avoid errors in Visual Studio code.
static with functions to avoid compile-time errors.
Check out this article too.