2

Suppose I have a header file myheader.h defined as follows:

#ifndef MY_HEADER
#define MY_HEADER

int MyFunction(int x)
{
    return x + 1;
}

#endif

Then, I have two source files which both #include this header file. This gives me a compile error:

multiple definitions of 'MyFunction(int)'

Why isn't the include guard in my header file preventing it from being defined twice?

Karnivaurus
  • 22,823
  • 57
  • 147
  • 247
  • 3
    If those two source files are linked, then they both have the definition compiled into them (as the definition is in the header). Leave the declaration in the header, but move the definition into a separate source file. – crashmstr Feb 22 '16 at 15:23
  • 1
    An include guard only protects against multiple inclusion in one translation unit (one source file). – Michael Burr Feb 22 '16 at 15:26

3 Answers3

4

You need to mark your function inline, like following:

#ifndef MY_HEADER
#define MY_HEADER

inline int MyFunction(int x)
{
    return x + 1;
}

#endif

Explanation:

Every time you include your .h in any .cpp file, you end up with a definition of the function. Linker doesn't like multiple definitions. However, if you mark function inline, you are telling compiler to make sure linker will be satisfied.

The real way of how to make the linker happy is dependent on the compiler and linker, but in practice, it boils down to two strategies:

  • Inlining the function - which means, the function definition is actually removed from the generated code. Instead, whatever the function was supposed to do would be done where the function was called.
  • Marking function as local name - linker knows that local names are specific to a particular file, and will always keep them separate.
SergeyA
  • 61,605
  • 5
  • 78
  • 137
1

The linker will be passed one definition per compilation unit that includes the header.

The linker will always want exactly 1 definition.

Consider defining the function in exactly one source file, or alternatively use an inline directive.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
0

Declaration (.h) is different from definition (.c, .cpp...)

A good practice is to declare a function in a header file, inside guard:

//file foo.h: can be included in other header or implementation files
#ifndef MY_HEADER
#define MY_HEADER 
int MyFunction(int x);
#endif

And to define a function in an implementation file:

//file foo.c: not included in other files.
#include "foo.h" // to assert function declaration and definition match
int MyFunction(int x)
{
    return x+1;
}
Mathieu
  • 8,840
  • 7
  • 32
  • 45
  • 1
    There is nothing **good practice** about it. Sometimes it is a suitable approach, sometimes it is not. – SergeyA Feb 22 '16 at 15:35