链接使用不同预处理器标志或 C 标准构建的库
Posted
技术标签:
【中文标题】链接使用不同预处理器标志或 C 标准构建的库【英文标题】:Linking libraries built with different preprocessor flags or C standards 【发布时间】:2013-01-24 08:18:22 【问题描述】:场景 1: 我想将一个新库(libA)链接到我的程序中,libA 是使用带有 -std=gnu99 标志的 gcc 构建的,而我的程序的当前库是在没有该选项的情况下构建的(假设 gcc 默认使用 -std=gnu89 )。
场景 2: libB 是使用一些预处理器标志构建的,如“-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED”以启用 XPG4 功能,例如msg_control 结构 msghdr 的成员。虽然 libC 不是在没有这些预处理器标志的情况下构建的,但它与 libB 相关联。
是错误的吗? 我关心的主要是结构定义不匹配。
谢谢。
【问题讨论】:
我为不同的优化做了很多,其中一个关键例程比程序的其余部分优化得更精细。 谢谢米哈伊尔,是的,我知道它应该在不同优化标志的情况下工作。我已经更新了我的问题,我担心的是结构定义不匹配。 【参考方案1】:场景 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
。接下来,您将其链接在一起,一切似乎都很好。然后在运行时一切都失败了,您可能很难调试为什么要从一个模块传递 int ,而期望在被调用方端浮动。
一些更棘手的情况可能包括条件定义的结构字段、调用约定、全局变量大小。
附:假设您所有的源代码都是用相同的语言编写的,只改变标准选项和宏定义。结合 C 和 C++ 代码有时真的很棘手,同意 Mikhail 的观点。
【讨论】:
【参考方案2】:我遇到的结构定义不匹配的几次是在组合 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.
【讨论】:
有趣,我做了一个实验,但没有看到这样的警告。但是我的实验只使用了 C 和 gcc。以上是关于链接使用不同预处理器标志或 C 标准构建的库的主要内容,如果未能解决你的问题,请参考以下文章
有 C++ 标准库 ifdef 或 ifndef 预处理器指令吗?