2012-02-15 73 views
4

我有rand.cpp和rand.hpp文件並且有rand_unif()函數。 我已將rand.hpp文件包含在sim_engine.hpp文件中。ld:重複的符號

在main.cpp文件中,我包含了sim_engine.hpp文件。 如果我運行生成文件,然後我得到這個錯誤

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。

+0

請確保您的頭部包含警衛 – shuttle87 2012-02-15 19:15:13

+0

聽起來像違反了[ODR](http:// stackoverflow。COM /問題/ 4192170 /什麼,恰好是一定義規則,在-C) – Flexo 2012-02-15 19:15:42

+0

在rand.hpp文件我已經的#ifndef _RAND_HPP_ 的#define _RAND_HPP_/#ENDIF衛士 – codereviewanskquestions 2012-02-15 19:17:12

回答

6

你有明顯在您的程序中多次定義了rand_unif。您可能只在文本代碼中定義一次,但是通過包含頭文件,該代碼會被編譯爲多個文件.o

你可能在rand.hpp定義rand_unif。這頭被列入由sim_engine.hpp,使包括sim_engine.hpp將自動獲得的rand_unif副本的任何.cpp文件包括在內。顯然,無論是的main.cppsim_engine.cpp包括sim_engine.hpp,所以這兩個的.o文件得到函數的副本。 C++禁止具有同一功能的多個定義,但它不要求強制執行該要求。 (它被稱爲單定義規則。)鏈接程序引起了您的注意。

有這個問題的兩個典型的解決方案:

  • 移動功能定義爲的.cpp文件; rand.cpp似乎是一個很好的候選人。確保rand.hpp只包含一個聲明,而不是一個定義。

  • 將頭文件中的定義更改爲inline。 C++對內聯函數的單定義規則作了例外。在rand.hpp申報前加inline

-1

我的猜測是你在你的代碼中包含了兩次函數的聲明。你可能想嘗試包裹 「rand.hpp」 本的全部夾雜物:

的#ifndef RAND_HPP
的#define RAND_HPP
的#include {文件路徑}
#ENDIF

+0

-1:包含警衛在鏈接時不存在。 – 2012-02-15 19:21:33

+1

的確如此。但是,如果你防範多個包含,那麼你的預處理器指令將確保你不會將重複的定義發送到編譯器和鏈接器。 但是,如果將它定義在單獨的.cpp文件中,宏將不提供任何保護。 – 2012-02-15 23:00:13

相關問題