链接使用不同预处理器标志或C标准构建的库

时间:2013-01-24 08:18:22

标签: c gcc linker shared-libraries

情景1: 我想将一个新库(libA)链接到我的程序中,libA是使用带有-std = gnu99标志的gcc构建的,而我的程序的当前库是在没有该选项的情况下构建的(我们假设gcc默认使用-std = gnu89) )。

场景2: libB是使用一些预处理程序标志构建的,例如“-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED”以启用XPG4功能,例如: struct msghdr的msg_control成员。虽然libC不是在没有这些预处理器标志的情况下构建的,但它是与libB链接的。

链接使用不同预处理器标志或C标准构建的库是错误的吗? 我关心的主要是结构定义不匹配。

感谢。

2 个答案:

答案 0 :(得分:0)

我遇到的结构定义不匹配的几次是在组合C和C ++代码时,在这些情况下有一个明确的警告,发生了一些可怕的事情。 像

这样的东西
/usr/lib/gcc/i586-suse-linux/4.3/../../../../i586-suse-linux/bin/ld: Warning: size of symbol `tree' changed from 324 in /tmp/ccvx8fpJ.o to 328 in gpu.o

See that question.

答案 1 :(得分:0)

场景1对您来说完全安全。 GCC中的std=选项检查代码是否与标准兼容,但与ABI无关,因此您可以随意将预编译代码与不同的std选项组合。

场景2可能不安全。我将在这里放一个简单的例子,真实案例可能会更棘手。

考虑一下,你有一些功能,比如:

#ifdef MYDEF
int foo(int x) { ... }
#else
int foo(float x) { ... }
#endif

您使用a.o-DMYDEF编译b.o,而bar中的a.o函数foo调用b.o中的函数{{1}} }。接下来,将它链接在一起,一切似乎都很好。然后一切都在运行时失败,你可能很难调试为什么从一个模块传递int,同时期望在被调用方浮动。

一些棘手的案例可能包括条件定义的结构字段,调用约定,全局变量大小。

P.S。假设您的所有源都使用相同的语言编写,只改变标准选项和宏定义。结合C和C ++代码有时候非常棘手,同意Mikhail。