簡體   English   中英

“C ++編譯器錯誤的多重定義

[英]“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;

  1. 項目清單

     while keeping the Actual code in the cpp : int Var_Global; 

並確保1.包含標題,然后2.鏈接代碼。

鏈接代碼一次,只有一次,並且只有一個數據副本,如果你整天都可以包含標題,這告訴其他代碼鏈接時會有一份數據副本。

我看到很多人把代碼放在頭文件中,雖然這可能在某些情況下有用,但這是一個壞習慣,遲早會引起問題。

問候,

Prashanta

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM