2011-03-03 53 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就更加困难。