0

I am getting error:

/usr/bin/ld: /tmp/ccCbt8ru.o: in function `some_function()':
Thing.cpp:(.text+0x0): multiple definition of `some_function()'; /tmp/ccc0uW5u.o:main.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

when building a program like this:


main.cpp

#include "common.hpp"
#include "Thing.hpp"

int main() {
    some_function();
}

common.hpp

#pragma once
#include <iostream>

void some_function() {
    std::cout << "something" << std::endl;
}

Thing.hpp

#pragma once

class Thing {
public:
    void do_something();
};

Thing.cpp

#include "Thing.hpp"
#include "common.hpp"

void Thing::do_something() {
    some_function();
}

I'm compiling with: g++ main.cpp Thing.cpp -o main.out

I've also tried using include guards instead of #pragma once, but it didn't seem to work either. Is there something I am forgetting here?

Jorengarenar
  • 2,705
  • 5
  • 23
  • 60
Thuong Vo
  • 77
  • 11
  • 1
    Include guards prevent multiple inclusions of a header in a single cpp file (technical term: translation unit). You have multiple cpp files. Each includes. Each gets its own definition of `some_function`. Consider making `some_function` `inline`. – user4581301 Sep 07 '21 at 05:24

1 Answers1

2

#pragma once and include guards can only prevent multiple definitions in a single translation unit (a .cpp file). The individual units know nothing about each other, and so cannot possibly remove the multiple definition. This is why when the linker links the object files, it sees the multiple definitions still.

To solve this issue, change common.hpp to:

#pragma once

void some_function();

This tells the compiler that there is some code for some_function. Then, add a file common.cpp that contains the code for the common.hpp header:

#include "common.hpp"
#include <iostream>

void some_function() {
    std::cout << "something" << std::endl;
}

Finally, change the g++ command to:

g++ main.cpp common.cpp Thing.cpp -o main
Thuong Vo
  • 77
  • 11