6

I have rand.cpp and rand.hpp file and have rand_unif() function. I have included rand.hpp file in sim_engine.hpp file.

In main.cpp file, I have included sim_engine.hpp file. If I run makefile then I got this error

ld: duplicate symbol rand_unif()    in sim_engine.o and main.o for architecture x86_64
collect2: ld returned 1 exit status

sim_engine.hpp is the only place where includes rand.hpp. main.cpp does not include rand.hpp but sim_engine.hpp.

I don't understand why I am getting the duplicate symbol error.

#mod_simu.make project makefile

mod_simu : main.o rand.o graph.o street.o isection.o vehicle.o event.o FEL.o sim_engine.o clock.o
    g++ -o mod_simu main.o rand.o graph.o street.o isection.o vehicle.o event.o FEL.o sim_engine.o clock.o

main.o : main.cpp   
    g++ -c main.cpp

rand.o : rand.cpp
    g++ -c rand.cpp

graph.o : graph.cpp graph.hpp street.hpp isection.hpp
    g++ -c graph.cpp

street.o : street.cpp street.hpp
    g++ -c street.cpp

isection.o : isection.cpp isection.hpp street.hpp
    g++ -c isection.cpp

vehicle.o : vehicle.cpp vehicle.hpp
    g++ -c vehicle.cpp

event.o : event.cpp event.hpp
    g++ -c event.cpp

FEL.o : FEL.cpp FEL.hpp
    g++ -c FEL.cpp

sim_engine.o : sim_engine.cpp sim_engine.hpp
    g++ -c sim_engine.cpp

clock.o : clock.cpp clock.hpp
    g++ -c clock.cpp
clean:
    rm *.o mod_simu

#end

This is the makefile I have.

codereviewanskquestions
  • 13,460
  • 29
  • 98
  • 167

2 Answers2

13

You have evidently defined rand_unif multiple times in your program. You probably only define it once in textual code, but through header inclusion, that code gets compiled into multiple .o files.

You probably defined rand_unif in rand.hpp. That header gets included is included by sim_engine.hpp, so any .cpp file that includes sim_engine.hpp will automatically get a copy of rand_unif. Apparently, both main.cpp and sim_engine.cpp include sim_engine.hpp, so both those .o files get a copy of the function. C++ forbids having multiple definitions of the same function, but it does not require enforcement of that requirement. (It's called the one-definition rule.) The linker has caught you.

There are two typical solutions to the problem:

  • Move the definition of the function into a .cpp file; rand.cpp seems like a good candidate. Make sure that rand.hpp contains only a declaration, not a definition.

  • Change the definition in the header file to be inline. C++ makes an exception to the one-definition rule for inline functions. Add inline before the declaration in rand.hpp.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
-2

My guess is that you are include the declaration of the function twice somewhere in your code. You may want to try wrapping all inclusions of "rand.hpp" with this:

#ifndef RAND_HPP
#define RAND_HPP
#include {path to file}
#endif

Max Seiden
  • 45
  • 3
  • 1
    That's true. But if you guard against multiple includes, then your preprocessor directives will ensure you won't be sending duplicated definitions to the compiler and linker. But yes, in the case of defining it in separate .cpp files, macros will not provide any protection. – Max Seiden Feb 15 '12 at 23:00