在macOS或Linux上,C标准库结构是否兼容编译器和库版本?

时间:2018-01-22 19:40:47

标签: c linux macos gcc clang

我的主机应用程序接管了例如来自动态库的FILE对象。即使我的宿主应用程序和动态库使用不同版本的clang / gcc编译,我是否可以安全地在此对象上调用fclose()

背景

在Windows上(具有不同的VS运行时),这将是非法的,我必须首先从动态库使用的运行时库中提取fclose()函数,因为所有运行时都有自己的池和内部结构文件或内存对象。

Windows中的情况说明如下:

diagram of library interactions on Windows

此限制是否也适用于Linux和macOS?

3 个答案:

答案 0 :(得分:4)

问题不在于您的应用程序和动态库是否使用不同版本的clang和/或gcc编译。问题在于,最终是否存在一个底层C库来操纵一种FILE *对象并且具有fclose()的一个兼容实现。

至少在MacOS和Linux下,所有这些问题的答案可能都是"是"。根据我的经验,很难将两个不同的,不兼容的C库混合在一起;你必须真正开展工作。

附录:但我想我应该承认,我的经历可能会过时。根据我的经验,在任何类Unix系统上,只有一个C库,通常是/lib/libc.{a,so}。但我收集了#34;现代"编译器倾向于在特殊位置访问自己的编译器和版本特定的库,这意味着您担心的场景可能是个问题。对我来说,似乎这种方式是疯狂,但是再一次,似乎越来越多的世界似乎在接受dependency hell,而不是试图消除它。

答案 1 :(得分:1)

对于使用由不同编译器编译的代码的一个编译器设计的库通常不安全。编译器可以使用内部例程或接口生成在标准库中实现标称函数的代码,并且在为另一个编译器设计的库中,这些例程或接口可能不同或缺失。

从一个库中获取指向某些内部数据结构的指针并将其与另一个库一起使用也不安全。

如果源只是使用一个编译器的不同版本编译(例如,clang 73和clang 89),而不是不同的编译器(例如,Apple clang与GCC),编译器可能会提供关于库兼容性的一些保证。您必须检查其文档。或者,如果编译器打算使用随操作系统提供的库,则可以使用。同样,您必须检查其文档。

答案 2 :(得分:1)

在Linux上,如果您的代码和其他库动态链接到同一个库(例如libc.so.6),则两者都将在运行时获得该库的相同版本和实现。您可以使用ldd检查给定动态库链接到哪些库。

如果要链接到在支持库中静态链接的库,则需要小心地将任何结构传递给相同版本的库。但libc++libstdc++比使用libc更有可能实现这一目标。

因此,不要将您的库静态链接到另一个库,然后传递一个需要客户端代码的数据结构,以便单独链接到同一个库。