Reputation: 26356
I have created custom random number generators and placed their global functions in a file I called SamRandom.h. The file looks as follows:
#ifndef _SAM_RANDOM_H
#define _SAM_RANDOM_H
#include <cstdlib>
#include <ctime>
void InitialiseRandomSeed()
{
//...
}
//...
#endif
I'm working in a very complex object-oriented program that has many different components from here and there. Everytime I add a file that is anyhow related to this file, I get the following conflict message:
LaserBase.obj:-1: error: LNK2005: "void __cdecl InitialiseRandomSeed(void)" (?InitialiseRandomSeed@@YAXXZ) already defined in main.obj
error: LNK1169: one or more multiply defined symbols found
On MSVC, and on MinGW I get:
In function `Z20InitialiseRandomSeedv':
SamRandom.h:8: multiple definition of `InitialiseRandomSeed()'
error: first defined here
:-1: error: collect2: ld returned 1 exit status
Why is this happening? I thought that preprocessor directive is supposed to prevent this problem from happening... this is really driving me crazy!!!
P.S.: The problem is independent of the function name.
Thanks for any efforts
Upvotes: 0
Views: 170
Reputation: 6107
The header guards ensure that the function is not being defined multiple times in a single compilation unit (.cpp file). However, they don't prevent the function from being defined a single time in multiple compilation units. This is because the header contains the definition of the function, so every .cpp that includes the header has its own definition of the function.
You could move the definition to SamRandom.cpp and instead declare the function in the header like so:
void InitialiseRandomSeed();
Alternatively you could specify that the function is inline which would make multiple definitions acceptable:
inline void InitialiseRandomSeed()
{
//...
}
Assuming that the function is not performance-critical and does not get called frequently, I would go with the former approach. This keeps headers more readable and (in general) decreases compile times.
Upvotes: 2
Reputation: 9319
When you include your file in a .cpp file the preprossesor directly copys it into that file. So when you compile that .cpp file the object file (a step the compiler always does even if you don't recognize) will contain that function. If you include it in more than one .cpp file each object file will contain the function. When the linker trys to link all object files to an executable it finds the function x-times and gives that error. "one or more multiply defined symbols found" says it found one of your functions (or variables) more than once and doesnt know how to deal with it.
To avaoid this you should only put the signature of you function e.g.
//whatever.h
#ifndef _SAM_RANDOM_H
#define _SAM_RANDOM_H
void InitialiseRandomSeed();
#endif
in ther header file and put the implementation into a seperate .cpp file:
//whatever.cpp
#include "whatever.h"
#include <cstdlib>
#include <ctime>
void InitialiseRandomSeed()
{
//...
}
Upvotes: 2
Reputation: 4770
You could separate the definition into a .cpp file and just declare the function in the header.
Upvotes: 1