Anselmo GPP
Anselmo GPP

Reputation: 451

Multiple definitions when using #ifdef

I am having a problem when compiling: Multiple definitions of "myFunction()" I will greatly simplify the problem here. Basically, I have 3 files: "main", "header", and "myLibrary".

    #include "header.hpp"

    int main() {  }
    #ifndef HEADER_HPP
    #define HEADER_HPP

    #include "myLibrary.hpp"

    // ...

    #endif
    #include "header.hpp"

    // ...
    #ifndef LIB_HPP
    #define LIB_HPP

    #if defined(__unix__)
    #include <dlfcn.h>
    std::string myFunction() { return std::string(); }
    #endif

    #endif
    #include "myLibrary.hpp"

    //...

So, why does the compiler say that I have Multiple definitions of "myFunction()"?

One clue I found: When I take header.cpp and erase the line that says #include "header.hpp", the program compiles without complaining. On the other hand, if I erase myFunction (from myLibrary.hpp) instead, the program also compiles without complains

Upvotes: 2

Views: 2657

Answers (3)

user12211554
user12211554

Reputation:

You should to define functions in the .cpp files, not in the header files. You declare them in the header files. What you're doing is defining it in the header file, so when it gets included into multiple files, the function is getting duplicated. Cross-file duplicate symbols will throw an error, unless they're static.

myLibrary.cpp:

#include "myLibrary.hpp"
#ifdef(__unix__)
std::string myFunction() { return std::string(); }
#endif

myLibrary.hpp:

#ifndef LIB_HPP
#define LIB_HPP

#if defined(__unix__)
#include <dlfcn.h>
#include <string>
std::string myFunction();
#endif

#endif

Upvotes: 1

dreamlax
dreamlax

Reputation: 95335

Include guards only prevent the same header from being included twice within the same translation unit, which in practice is usually a single .cpp file. For example, it prevents errors when doing this:

#include "header.h"
#include "header.h"

int main()
{
}

But, more generally, it means that it doesn't matter if you've include a header that has already been included as a dependency of another header.

However, if you have two .cpp files include the same header, and that header contains the definition of a function (such as your myLibrary.hpp) then each .cpp file will have its own definition (the include guard won't help because the header is being included in two separate translation units / .cpp files).

The simplest thing to do is to declare the function in the header, which tells every file that includes your header that the function exists somewhere, and then define it in the .cpp file so that it is only defined once.

Upvotes: 3

Remy Lebeau
Remy Lebeau

Reputation: 596256

You are defining the body of the function inside the header file. So every translation unit that you include that header in (in this case, main.cpp and header.cpp) will end up with its own copy of that function body. And when you try to link those multiple units together, you get the "duplicate definition" error.

The function needs to be declared in the hpp file, and defined in the cpp file:

myLibrary.hpp

#ifndef LIB_HPP
#define LIB_HPP

#if defined(__unix__)
#include <dlfcn.h>
#include <string>
std::string myFunction();
#endif

#endif

myLibrary.cpp

#include "myLibrary.hpp"

#if defined(__unix__)
std::string myFunction()
{
    return std::string();
}
#endif

//...

Upvotes: 5

Related Questions