2011-03-03 51 views
1

我將一些可怕的傳統C++代碼從gcc 3.x移植到4.x 在頭文件中有這樣的構造:extern class:從gcc 3.x移植到4.x時未定義的引用

extern class ErrorLog 
{ 
    . . . 
} error_log, debug_log; 

在3.X它編譯和工作正常,但在4.x的,我有很多形式

undefined reference to `error_log' 

undefined reference to `ErrorLog::log(ErrorLog::LogAttr const&, char const*, ...)' 
+0

ErrorLog :: log在哪裏實現? error_log的實際定義在哪裏?聽起來像你的生成文件改變了,你錯過了一個.cpp文件。 – EboMike 2011-03-03 23:50:33

+0

ErrorLog的方法和實例error_log在ErrorLog.cc的其他地方執行。這是建立和聯繫。相同的代碼鏈接OK 3.x編譯器 – 2011-03-04 00:23:13

回答

0

EXTERN的錯誤是一個聲明,而不是定義。因此,您只聲明名稱error_logdebug_log,但不爲其分配存儲位置。您需要在其他地方定義這些變量(可能位於.cpp文件中)。

可能足以做到這一點,包括你提到的頭文件源文件: ErrorLog error_log, debug_log;

具有extern聲明整個類定義爲奇數雖然。

+0

對不起,我無法得到這個網站使用的任何標記方法的掛鉤。原諒我。 有一個單獨的文件ErrorLog.cc 的#include 「error.h」 錯誤日誌的error_log =錯誤日誌(ROOT_LOGGER_ID);' 錯誤日誌DEBUG_LOG =錯誤日誌(ROOT_LOGGER_ID);' 空隙的ErrorLog ::日誌(const int的level,const char * fmt,...) { ... } – 2011-03-04 00:28:43

+0

格式化:使用\'反引號\'。 – dappawit 2011-03-04 00:37:00

+0

由於某種原因,它正在吃掉我的新線。 #include「error.h」 ErrorLog error_log = ErrorLog(ROOT_LOGGER_ID); ErrorLog debug_log = ErrorLog(ROOT_LOGGER_ID);' 'void ErrorLog :: log(const int level,const char * fmt,...){...}' – 2011-03-04 00:54:47

1

我認爲這與一個bug report有關,因爲我後來引用了GCC。問題是,這是否定義了類型class ErrorLog?我建議你分開的定義和聲明,像這樣:

class ErrorLog{...}; 
extern ErrorLog error_log, debug_log; 

大概class ErrorLog定義別的地方太 - 最好你應該改變這種做法,它只是定義一次。

+0

我嘗試將定義和聲明分開,但沒有喜悅,我會再試一次。 – 2011-03-04 00:12:45

+0

當你分離它們時發生了什麼?你是否得到編譯器/鏈接器錯誤?什麼錯誤? – dappawit 2011-03-04 00:35:03

+0

同樣的事情發生了,沒有什麼不同,錯誤在鏈接階段顯示出來,但正如我所說的,使用相同源代碼和相同makefile的3.x g ++編譯器可以很好地工作 – 2011-03-04 00:59:38

0

解決方案原來是一個簡單的鏈接器排序問題。 error_log定義位於命令行早期列出的庫中,但直到以後才使用。 4.x鏈接程序不能像3.x鏈接程序那樣跟蹤定義的符號。在開始時添加-Xlinker -whole-archive解決了這個問題,儘管它自然會膨脹該對象。

更改排序也可以,但是歸檔集是自動生成的,所以如果不徹底改寫Makefile就更加困難。