GCC构建。预期的错误

时间:2013-01-09 03:51:11

标签: c++ gcc

我不是任何语言或GCC的专家。所以我的问题可能低于标准。

我正在使用GCC构建包含数千个CPP文件的代码库。在一个文件中说A.cpp我在B.cpp中调用了一些函数[B.cpp包含了定义为B.h的类的类方法定义]。构建很好。但后来我从makefile中排除了B.o。所以现在没有创建对象文件B.o。但是在这种情况下,由于A.cpp引用B.cpp中的函数,我在编译或链接阶段时会遇到错误。但是没有,代码仍然没有错误地构建。但当我将fn调用从A.cpp移动到另一个文件C.cpp时,它给了我一个链接器错误,这是我认为的预期行为。

这是预期的行为吗?我还检查了在构建期间创建的映射文件,其中列出了所有函数名称,即使未创建B.cpp的目标文件,映射中也存在B.cpp中的函数。所以我的问题是,当我从一个不属于构建的文件中调用函数时,为什么没有错误。我尝试删除以前版本中的所有目标文件和二进制文件,以清除可能存在的任何残留物,但无济于事。我没有线索。有人可以提供一些帮助吗?

在我的地图文件中,正常功能列为

80010820 T __gccmain

80010828 t __gccmain_end

但是B.cpp的fns列为

U CNvThread::ProcMsgReq(unsigned, void*)

U CNvDbMgrThread::Singleton(unsigned long)

3 个答案:

答案 0 :(得分:1)

如果B.o仍然存在于上一个版本中,它将与旧版本链接正常(除非某些重大更改)。如果你没有构建最终的可执行文件,并且只构建了A.o,那么这仍然没有问题,因为A.o引用了B中的函数,但是直到最后才与它们链接输出文件链接。

同样,如果B.o仍然存在于上一个版本中,则会使用它,这就是它出现在地图文件中的原因。

答案 1 :(得分:1)

听起来你有一个“makefile”:好。

默认情况下,“make”会(通常)尝试构建您的项目。无论如何,这是标准惯例。

通常,make也会有其他“目标”。例如,您可以键入“make clean”或“make cleanall”。如果存在这些目标,他们将删除您的二进制文件,因此您可以从头开始重建。

我怀疑当你重新运行“make”时,它会从你上一次构建中获取旧的二进制文件。你检查一下它是否存在?

否则,我猜你的项目从来没有真正需要它:)

运行“ld -M”生成地图(应该包含交叉引用)是确认这一点的好方法。

答案 2 :(得分:0)

链接器忽略了预期的错误,因为由于A.o而未编译创建#if的行。

#if (OBJ_A_SUPPORTED)

A* a = new A();

#endif

移动了OBJ_A_SUPPORTED定义的头文件。

这导致链接器从A.cpp中排除fns,然后在B.cpp中删除对fns的调用。所以没有链接器错误。好好看看地图文件可能会在这种情况下产生一些线索,我完全错过了。