I’m working with Code::Blocks. When I create a header-file foo.h and put forward-declarations as well as implementation into it, compilation works fine. Creating a foo.cpp file and putting nothing into it still works. But when I include the header-file within the implementation file, but keep the implementation in the header-file, I get an error about multiple declarations.
Example from my current Project
// header-file `GKit/math/blendprocs.cpp`
#include "GKit/utils/Color.h"
#ifndef _GKIT_MATH_BLENDPROCS_H_
#define _GKIT_MATH_BLENDPROCS_H_
namespace GKit {
namespace math {
void blendAoverB(GKIT_COLORBLENDPROC_ARGSX) {
D.a = A.a + (1 - A.a) * B.a;
D.r = (A.a * A.r + (1 - A.a) * B.a * B.r) / D.a;
D.g = (A.a * A.g + (1 - A.a) * B.a * B.g) / D.a;
D.b = (A.a * A.b + (1 - A.a) * B.a * B.b) / D.a;
GKIT_UTILS_COLOR_NORMALIZE(D);
}
}
}
#endif // _GKIT_MATH_BLENDPROCS_H_
// implementation-file `GKit/math/blendprocs.cpp`
#include "GKit/math/blendprocs.h"
// Compilation output
-------------- Build: Debug in GKit ---------------
Compiling: GKit\math\blendprocs.cpp
Linking console executable: bin_debug\GKit.exe
build_debug\GKit\math\blendprocs.o:C:\Users\niklas\Desktop\GKit/./GKit/math/blendprocs.h:10: multiple definition of `GKit::math::blendAoverB(GKit::utils::Color const&, GKit::utils::Color const&, GKit::utils::Color&)'
build_debug\main.o:C:\Users\niklas\Desktop\GKit/./GKit/math/blendprocs.h:10: first defined here
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
2 errors, 0 warnings
Can you please help me understanding this error?
You have a definition in a header. That definition will be duplicated in any source file that includes that header; since it’s usually an error to have more than one definition in a program, the build fails. This is known as the One Definition Rule, sometime cryptically referred to as ODR.
The two best options are either:
inlineto the definition; this relaxes the rule and allows multiple definitions in a program, as long as they are all identical.Also, you shouldn’t use reserved names for your include guards; you should remove the initial
_from_GKIT_MATH_BLENDPROCS_H_; and it’s better to put those guards right at the start of the header, before any#includedirectives.