Reputation: 125
I have defined a function within a header file. In debug, it compiles and links fine. In release, I get the compile error "multiple definition of `blah::blah(blah& blah)'" for every object file of every class that includes the header.
I'm using gcc-4.8.1. I can't post up the actual code, this version has names changed to protect the innocent:
#ifndef INCLUDE_SMELLS_FUNNY
#define INCLUDE_SMELLS_FUNNY
#include "ParentClass.h"
#include "ChildClassA.h"
#include "ChildClassB.h"
namespace someplace {
bool smellsFunny(const ParentClass& someData) {
// All ChildClass As smell funny
if(dynamic_cast<const ChildClassA*>(&someData)) {
return true;
}
// If ChildClass B, need to check if smells funny
const ChildClassB* childB = dynamic_cast<const ChildClassB*>(&someData)
if(childB) {
return childB->MoreThanAWeekOld();
}
// Default is smells OK
return false;
}
}
#endif // INCLUDE_SMELLS_FUNNY
I haven't been able to find which gcc flag is responsible. Of course, a fix is just to move the implementation into a cpp file. But why is this necessary? Why does this happen only in release?
Upvotes: 2
Views: 1751
Reputation: 227418
Since you have placed the function definition in the header, you need to mark it inline
:
inline bool smellsFunny(const ParentClass& someData) { ...
This is because every place in which you include the header will have a definition of the function, breaking the one definition rule (ODR). inline
lets you work around the ODR.
As to why there is no problem in release mode, that doesn't make sense: the code is not correct. It could be that release mode is declaring the function inline for you.
Upvotes: 2
Reputation: 311018
I can not say exactly but maybe in the debug mode the function is considered as inline function.
Upvotes: 1
Reputation: 16824
If the function is in a header file, you need to declare it inline
, unless it's defined within a class.
Upvotes: 1
Reputation: 409196
It's because you define the function in a header file, and then include that header file in multiple source files. That means the function will be defined in each source file (technically, translation unit) where you include the header.
There are a couple of solutions to this:
static
. That means that each definition in the translation units will not be exported.inline
. This works basically the same as the first alternative.For a small function like the one you have, then alternative 2 might be a good one. If you have a larger function, that can't easily be inlined, you should go with alternative 3.
Also, if you go with number 3, then you don't need to include the header files, and then lessen the risk of circular inclusion.
Upvotes: 2