I have a util.h
containing a function which will be used in a.h
and 'b.h', and further more, a.h
and b.h
will include each other in order to access some classes defined in each other.
//util.h
#ifndef _UTIL_H_
#define _UTIL_H_
#include <iostream>
void foo()
{
std::cout << "foo\n";
}
#endif
//a.h, it has a a.cpp
#ifndef _A_H_
#define _A_H_
#include "util.h"
#include "b.h"
//some classes' definition
#endif
//b.h, it has a b.cpp
#ifndef _B_H_
#define _B_H_
#include "util.h"
#include "a.h"
//some classes' definition
#endif
My problem is that, I got multiple definition
error for foo
. How?
I thought the problem might be that, a.h
includes util.h
and b.h
, and b.h
includes util.h
once again, so I got multiple def error. But it can't seem to make sense, because in util.h
I wrote #ifndef/#define
guards.
Anyone can give me a help, thanks.
Your problem is caused by defining rather than simply declaring
foo
insideutils.h
For this example, assume that we have:
a.cpp
b.cpp
main.cpp
After preprocessing, but before compilation, your files now look like this (this is a simplification, but you get the idea):
a.cpp
b.cpp
main.cpp
Now when you compile, you have 3 definitions of
foo
(they're all identical, but this is irrelevant). After compilation, there is no way for the linker to know which definition to pick for any given call tofoo
and so it generates an error.Instead of defining
foo
in the header, define it inutils.cpp
and only put a declaration inutils.h
, e.g.utils.h
or, alternately, declare
foo
asstatic
orinline
:utils.h
This is something you need to do only if you want to inline your function. In this case, the compiler needs a definition of the function in every translation unit where it is used, as it essentially becomes a compile-time macro.