1

场景 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 标准构建的库是否错误?我关心的主要是结构定义不匹配。

谢谢。

4

2 回答 2

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

看到那个问题。

于 2013-01-24T08:40:35.330 回答
0

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

场景 2 可能不安全。我在这里只举一个简单的例子,实际情况可能要复杂得多。

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

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

a.o并且您可以在有-DMYDEFb.o没有的情况下进行编译,并bara.o调用函数fooin 中调用函数b.o。接下来,您将其链接在一起,一切似乎都很好。然后在运行时一切都失败了,您可能很难调试为什么要从一个模块传递 int ,而期望在被调用方方面浮动。

一些更棘手的情况可能包括条件定义的结构字段、调用约定、全局变量大小。

PS 假设您所有的源代码都是用相同的语言编写的,只改变标准选项和宏定义。有时结合 C 和 C++ 代码真的很棘手,同意 Mikhail 的观点。

于 2013-01-24T09:09:01.810 回答