ld:重复的符号

时间:2012-02-15 19:10:45

标签: c++ makefile

我有rand.cpp和rand.hpp文件并且有rand_unif()函数。 我在sim_engine.hpp文件中包含了rand.hpp文件。

在main.cpp文件中,我已经包含了sim_engine.hpp文件。 如果我运行makefile然后我收到此错误

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是包含rand.hpp的唯一地方。 main.cpp不包括rand.hpp而是sim_engine.hpp。

我不明白为什么我会收到重复的符号错误。

#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

这是我的makefile。

2 个答案:

答案 0 :(得分:8)

您在程序中已经多次明确定义rand_unif。您可能只在文本代码中定义一次,但通过包含头文件,该代码将被编译为多个 .o 文件。

您可能在 rand.hpp 中定义了rand_unif。包含的标头包含在 sim_engine.hpp 中,因此任何包含 sim_engine.hpp 的.cpp文件都会自动获得rand_unif的副本。显然, main.cpp sim_engine.cpp 都包含 sim_engine.hpp ,因此这些 .o 文件都得到了该功能的副本。 C ++禁止具有相同功能的多个定义,但不要求强制执行该要求。 (它被称为一个定义规则。)链接器已经抓住了你。

这个问题有两种典型的解决方案:

  • 将函数的定义移动到 .cpp 文件中; rand.cpp 似乎是一个很好的候选人。确保 rand.hpp 只包含声明,而不是定义。

  • 将标题文件中的定义更改为 inline 。 C ++对内联函数的单定义规则进行了例外处理。在 rand.hpp 中的声明之前添加inline

答案 1 :(得分:-1)

我的猜测是你在代码中的某处包含了两次函数的声明。你可能想尝试用这个包装“rand.hpp”的所有包含:

  

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