2012-07-20 62 views
2

我无法解释我在链接我的代码时看到的行为。也许有人有一个想法是怎么回事...包含语句在链接步骤中的顺序如何?

我有使用GNU Automake工具作为其构建系统(所有Linux下)的多个文件C++项目。

添加源文件和头文件后(让我们称之为util.ccutil.h)到项目,并具有调用来自新添加的文件,我具体情况取决于include得到一个链接错误的功能已经存在的源文件(calc.cc)声明出现。我再说一遍:错误发生在链接步骤中,编译运行良好!

例子:

calc.cc:

#include "file1.h" 
#include "file2.h" 
#include "file3.h" 
#include "file4.h" 
#include "util.h" // new header 

该版本编译罚款:

我时,把新的包含语句在预先存在的语句的结束,就像得到一个错误。但链接产生一个错误(未找到符号)!

现在,当改变这

#include "util.h" // new header 
#include "file1.h" 
#include "file2.h" 
#include "file3.h" 
#include "file4.h" 

然后编译和连接运行正常!

由于链接只读取.o文件,这一定意味着不同的内容取决于其中包括出现语句生成。怎么会这样?

编译为g ++(GCC)4.4.6

+0

有可能是在'util.h'中定义的宏防止被包括在随后的头文件中的一个的函数或变量声明。 – hmjd 2012-07-20 10:29:40

回答

1

机会是util.h具有改变其他文件中的一个的行为的#define。

确定发生了什么的最佳机会将涉及检查这些头文件以找到缺失符号的名称,并通过编译calc.cc的“工作”和“非工作”方式获得预处理器输出,并比较这两个文件。

1

简单,头文件可以(重新)定义哪些可以改变后的宏的解释宏。

例如,在上述的例子中,如果确实file1.h

#define lseek lseek64 

和util.h具有调用lseek的内联函数,然后根据不同的包括顺序生成的目标代码将有一个符号上参考lseek或lseek64。

这就是为什么项目往往有config.h中(由autoconf生成)规则首次列入。

0

你absolutley正确的:不同的对象代码是在两种情况下产生的。正如@hmjd所指出的,很可能util.h中有一个宏是其中一个(.h或.c)文件使用的,并且任何未声明的被称为identifier的文件都被编译器假定为一个函数 - 这是很可能是这里的错误。