[英]“Multiple definition of” C++ compiler error
在我的一個課程中,我似乎無法擺脫這些看似隨意的編譯錯誤。 我得到了4個錯誤,例如:
multiple definition of `draw_line(float, float, float, float)'
和
multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'
在方法中間標記的。
我也一直在另一個方法的中間得到multiple definition of `stack'
。 stack
是一個完全不同的文件中的全局變量。 它甚至沒有在文件中提到我收到錯誤。
我嘗試將容易出錯的文件分成.h和.cpp文件(最初只是一個.cpp)而且沒有任何關於更改的錯誤...
我沒有重復的方法。 我只有一個#include
of lines.h,並且在開頭有一個#ifndef
子句。 所有這些錯誤都出現在.cpp文件中。
任何想法可能是什么?
好吧,我得到了代碼:
lines.cpp是我從教師那里收到的轉換后的.c文件。 為了以防萬一,我包含了makefile,因為我總是遇到問題。 我還注釋了錯誤在文件中標記的確切位置,但它們看起來很隨意,所以我不知道它是否特別重要。 我放棄了.h文件,因為它沒有解決任何問題或幫助。 我相信沒有它就會更容易找到錯誤。
這是請求的main.cpp文件 (沒有.h)。
我重新制作了lines.h文件,因為我仍然收到:
multiple definition of `draw_line(float, float, float, float)'
和
multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'
lines.cpp文件中的錯誤,但multiple definition of `stack'
錯誤的multiple definition of `stack'
現在位於ThreeD.cpp文件中的隨機位置(現在由注釋標記)。 更新:此錯誤已得到修復,文件已修改為顯示:
我搞砸了一些全局變量extern,但它似乎並沒有影響任何東西。
您可能在頭文件中包含函數定義。 包括inline
關鍵字,以便它們不會被每個目標文件導出,或者將它們放在自己的.cpp
文件中。
對於全局變量,您需要在頭文件中使用extern
關鍵字。 否則,每個目標文件都會導出它們自己的變量,並且鏈接器會混淆哪個是正確的變量。
你為什么在ThreeD.cpp中#include lines.cpp? 這很不尋常。
你的makefile需要lines.o,所以你要編譯lines.cpp。 lines.cpp中定義的任何內容都將在lines.o中以及ThreeD.o中。
在lines.cpp中有一個有趣的注釋:
Don't forget to put declarations in your .h files.
我認為教師希望你將lines.cpp分成.h和.cpp。
摘自lines.cpp:
/* These go in your .h file or in lines.h */
/*
Line drawing header.
*/
void draw_line(float, float, float, float);
int near_far_clip(float, float, float *, float *, float *, float *,
float *, float *);
我懷疑這兩個聲明是lines.h中應該唯一的。
請發布一些代碼段。 也許你在類聲明和外部定義你的方法?
class X {
void foo(); // No definition, just declaration
void bar() {} // Declaration + definition
};
void X::foo() {} // First Definition, OK
void X::bar() {} // Already defined, ERROR
檢查包括拼寫錯誤的警衛。
檢查您的make選項,也許有人編譯成多個目標文件。
嘗試排除部分文件和代碼,直到找不到錯誤原因。
編輯:
修復包含* .cpp文件。 他們應該聯系起來。
如前所述 - 這里沒有足夠的信息來正確診斷。
但是如果draw_line
等是在頭文件而不是源(cpp)文件中定義的,那么您可能會在頭文件中聲明為內聯的方法,這些方法實際上並沒有正確內聯。 在這種情況下,包含標頭的每個.cpp文件將生成自己的draw_line
函數定義,並在鏈接時生成警告。
如果您使用的#defined INLINE宏來自已被遺忘或刪除的系統標頭,並且由於某種原因INLINE被預處理為無效,則會發生這種情況。
例如:
//Lines.h
#define GCCC //Note the typo
#if defined(GCC)
#define INLINE inline
#elif defined (MSVC)
#define INLINE __inline
#else
#define INLINE //Due to the typo, INLINE will be turned into nothing
#endif
INLINE void draw_line(float x1, float y1, float x2, float y2)
{
//Draw the line
}
//File1.cpp
#include "lines.h" //will define draw_line
//File2.cpp
#include "lines.h" //will also define draw_line
並且鏈接File1.cpp和File2.cpp將生成多個聲明錯誤
#ifndef THREED_H_
#define THREED_H_
#endif /* THREED_H_ */
刪除或評論這些行,這對我有用
多個定義錯誤是鏈接器錯誤,但沒有更多信息,很難診斷它們。 檢查同一文件在鏈接器命令中沒有出現兩次,並且頭文件只包含聲明,沒有定義。
沒有看到代碼,真的沒有幫助你。 編譯器清楚地要求於你的相反( 存在至少一個重復的定義)。
嘗試用最少的例子重現錯誤。 您是否嘗試在命令行中編譯Eclipse之外的代碼? 結果如何?
嗨,我在這里看到的基本規則適用於ll。 我將解釋這些錯誤中的事情是如何發生的以及那些錯誤:讓我們舉一個 “制作全局變量”的 例子
不要混淆頭文件,對於cpp文件。 標題只是允許多個文件項目在鏈接之前具有公共接口。
1.列表項
您應該在標頭中提供有關全局變量的信息:
extern int Var_Global;
項目清單
while keeping the Actual code in the cpp : int Var_Global;
並確保1.包含標題,然后2.鏈接代碼。
鏈接代碼一次,只有一次,並且只有一個數據副本,如果你整天都可以包含標題,這告訴其他代碼鏈接時會有一份數據副本。
我看到很多人把代碼放在頭文件中,雖然這可能在某些情況下有用,但這是一個壞習慣,遲早會引起問題。
問候,
Prashanta
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.