The Quantum Physicist
The Quantum Physicist

Reputation: 26356

C++: File conflicting with itself

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

Answers (3)

John McFarlane
John McFarlane

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

Haatschii
Haatschii

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

Anon Mail
Anon Mail

Reputation: 4770

You could separate the definition into a .cpp file and just declare the function in the header.

Upvotes: 1

Related Questions