2013-04-27 69 views
0

我有一個Visual Studio項目3個文件:test.cppdate.cppmain.cpp -LNK2005,LNK1169錯誤, 「INT __cdecl克(無效)」 已經定義

TEST.CPP:(G @@ YAHXZ?)

int g() { return 0; } 

date.cpp:

/*totally empty*/ 

main.cpp中:

#include "test.cpp" 
#include "date.cpp" 

int main() { return g(); } 

據我所知,如果頭文件被多次調用,那麼在頭文件中定義函數會導致違反一維定義規則。但在這裏,我只從一個文件/翻譯單元中調用一次。爲什麼它仍在扔LNK2005?

+0

不包括CPPS。 – chris 2013-04-27 19:28:14

+0

@chris爲什麼?我認爲C++編譯器對擴展是盲目的。不是嗎? – 2013-04-27 19:30:08

+0

這不僅僅是你的問題。 – chris 2013-04-27 19:44:24

回答

2

要包括「TEST.CPP」中「的main.cpp」 - 這是最有可能的錯誤,如Visual Studio中也將編譯「test.cpp」作爲單獨的文件,然後將「test.obj」與「main.obj」(這些是由編譯器生成的文件)鏈接到「main.exe」中。當它在「test.obj」和「main.obj」中都找到「g()」時,它會顯示「嗯?爲什麼你有兩個這樣的」(或者是鏈接器術語中的「多個定義的符號」)。

解決方案是有一個「test.h」,聲明void g();,然後用它包含到「main.cpp」中。

+0

我希望我可以將三個答案合併爲一個。但是這與我實際想要問的最接近。所以,我的投票。 – 2013-04-27 20:13:08

2

由於test.cpp是在VS項目,它會被編譯並沿內襯main.cpp導致多個定義 - 除非你採取特別的措施來防止這種情況發生,比如從項目移除test.cpp或將其設定爲「從Build中排除「。

如果重命名temp.cpptest.h你會得到兩個好處:

  1. VS不會自動編譯.h,當它在一個項目,因爲它假定該文件旨在包含來自其他文件,而不是獨立編譯。
  2. 這將是大約打算使用的文件的程序員減少混亂
+0

這不是上面的錯誤嗎?它不應該是test.cpp而不是test.h?要求確定。 – 2013-04-27 20:08:33

+0

並感謝您的額外信息。我認爲編譯器對擴展是中立的。是不是我錯了! – 2013-04-27 20:14:18

+0

我修復了這個錯字。儘管你可以強制工具(VS和編譯器)處理這些文件,但是你可以根據擴展名做出一些默認假設。如果您以與預期不同的方式使用擴展程序,您也會不必要地與必須處理該項目的人員造成混淆。 – 2013-04-27 23:57:00

4

您不應該包括test.cppdate.cpp。相反,你應該寫test.hdate.h,並將其包括:

test.h

int g(); 

date.h

// Contains prototypes for functions inside date.cpp 

的main.cpp

#include "test.h" 
#include "date.h" 

int main() { return g(); }