且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

用现代的GCC编译抛出错误(多重定义)的旧C代码(在LINUX上)?

更新时间:2023-10-17 16:53:04

如果源是用-fcommon构建的,GCC允许多个定义相同类型的同名全局变量。来自gcc manual

-fcommon将未初始化的全局变量放置在公共挡路中。这允许链接器将不同编译单元中同一变量的所有暂定定义解析为同一对象,或解析为非暂定定义。此行为与C++不一致,并且在许多目标上意味着全局变量引用上的速度和代码大小损失。它主要用于使旧式代码能够无错误地链接。

GCC 10之前的默认值是-fcommon,在GCC 10中默认为-fno-common,从gcc 10 release notes开始:

GCC现在默认为-fno-common。因此,对各种目标的全局变量访问效率更高。在C语言中,具有多个试探性定义的全局变量现在会导致链接器错误。使用-fcommon时,此类定义在链接期间以静默方式合并。

这解释了为什么在使用GCC 10的环境中构建失败,但可以使用较旧的GCC版本构建。您的选择是将-fcommon添加到内部版本中,或者使用10之前的GCC版本。

或者正如@JohnBollinger指出的那样,另一个选项是修复代码以删除那些多个定义,并使代码严格符合C标准。