19

This function is global and is defined in the header file (temporarily I want to keep it there).

The header file also constitutes a particular class which has inline functions and one of those functions call this global function.

The source file doesn't contain any occurrences of the global function in question.

Any hints on cause of the error?

I can post the code if anyone is interested.

mainwindow.o: In function `tileForCoordinate(double, double, int)':
mainwindow.cpp:(.text+0x310): multiple definition of `tileForCoordinate(double, double, int)'
main.o:main.cpp:(.text+0xd0): first defined here
moc_mainwindow.o: In function `qHash(QPoint const&)':
moc_mainwindow.cpp:(.text+0x0): multiple definition of `qHash(QPoint const&)'
main.o:main.cpp:(.text+0x0): first defined here
moc_mainwindow.o: In function `tileForCoordinate(double, double, int)':
moc_mainwindow.cpp:(.text+0x150): multiple definition of `tileForCoordinate(double, double, int)'
main.o:main.cpp:(.text+0xd0): first defined here
collect2: ld returned 1 exit status
make: *** [SimpleRouting] Error 1
Aquarius_Girl
  • 21,790
  • 65
  • 230
  • 411

5 Answers5

32

mark it as inline:

 inline void globalfunc() { 
 }

although doing so means that it will no longer strictly be global - you will get a copy in each translation unit that uses the header, but the linker won't object to this.

  • Thank you very much, you were on dot. Now please bother to give an explanation on why it is needed to attach inline with the global functions defined in the .h files? Or if you have an appropriate link, then please share it. – Aquarius_Girl May 21 '11 at 09:34
  • 4
    @Anisha If you don't the the compiler generates the function with external linkage, which means the linker sees multiple functions with the same name and complains. Marking it as inline gives it local (basically file scope) linkage, so the linker sees the multiple functions as not being the same. –  May 21 '11 at 09:41
  • 1
    Thanks, and now I have to google more about *external linkage*. – Aquarius_Girl May 21 '11 at 09:48
  • 1
    @Anisha: Need to google when you can find it in SO :) . Check the question and its answere if it helps :: http://stackoverflow.com/questions/1358400/what-is-external-linkage-and-internal-linkage-in-c – Arunmu May 21 '11 at 10:05
  • 1
    And why doesn't this happen when you define template functions in the header (which is very common)? And: I thought include guards are there to prevent multiple definitions/declarations?! – bweber Oct 28 '15 at 09:51
  • @bweber Templates go with the translation unit that instantiate them so there are no multiple definitions if you instantiate them in two different cpp files – Spyros Mourelatos Oct 02 '20 at 10:57
10

If you put a function in the header it will be generated for each c/cpp file that includes that header leading to duplicates. Making it inline will help.

Edit, explanation

Header guards as the #ifndef, #define ... #endif construction is often called only prevent double and recursive inclusion in a single cpp file. This is relevant in the case where a source file includes headers A and B and B also includes A. Recursive inclusion would happen if A also included B.

Your problem arises because you have multiple .cpp files. During compilation of one cpp the compiler doesn't know about the existence of the other cpp files.

Notice that #include, #ifdef and friends are preprocessor directives. Preprocessing happens on source files before compilation (thought it is often regarded and done as part of the compilation process). The preprocessor basically is a text processor. For instance an #include is textually replaced with the contents of the header file. Contents of #ifdefs that evaluate to false are removed from the code. The actual compiler gets one single big file consisting of the cpp and all referenced include files which it translates into an object file.

Eelke
  • 20,897
  • 4
  • 50
  • 76
8

You have 2 options:

Mark it as inline, as explained by nbt, or as static.

inline will take the implementation of the global function from the source and copy it into wherever the function is called.

inline void global_func ()
{
...
}

static will tell the linker to not copy the code into the new object file but rather only reference it in the original.

static void global_func ()
{
...
}
Chad Befus
  • 1,918
  • 1
  • 18
  • 18
3

For a global function defined in a header file, declaring it within an un-named namespace should/will also work. According to C++ How to Program by Deitel, in C++ an unnamed namespace is preferable to static.

So you could do this:

// \file GlobalFunctions.h

namespace  // an un-named namespace
{

void GlobalFunctionOne() {...implementation...}

} // end un named namespace
Pranav Singh
  • 17,079
  • 30
  • 77
  • 104
MichaelC
  • 39
  • 1
-3
#ifndef SOMESTRING
#define SOMESTRING
... header code
#endif

The code of the header will only be included the first time.

George Kastrinis
  • 4,924
  • 4
  • 29
  • 46
  • 6
    Wrong. It will be included in every translation unit that uses it, which is what is causing the multiple definition errors. Include guards only prevent multiple inclusion in the SAME translation unit. –  May 21 '11 at 09:37
  • I know this, I have already included that in the .h but still the error prevailed, so I created this thread. – Aquarius_Girl May 21 '11 at 09:37