最近一个项目,用了mingw编译环境,报重复定义
xxxxx : multiple definition of _Exit
xxxxx: first defined here
xxxxx:multiple definition of llabs
…
multiple definition of atoll
multiple definition of strncasecmp
multiple definition of wtoll
…
好多,经过分析发现,原因是两个.c文件,每个文件里面都含有这些函数的定义,所有链接的时候报重复了,使用
x86_64-w64-mingw32-gcc.exe -E xx.c > a.txt
把预处理之后的内容导入到一个文件中,然后搜索这些重复定义的函数名,果然,原来都是一些应该inline的函数,但是前面没加static, 并且不知道什么原因竟然没有inline,就导致了重复定义了。
仔细查看里面头文件中的位置,然后到头文件中找到对应的位置,分析原因,发现了一个解决方案,就是CFLAGS里面加入一个参数
-D__CRT__NO_INLINE
这样预处理之后就不会包含那些不带static的inline了。
根源,应该是在windows的环境中的宏定义出现了问题,或者是某些对inline的处理的bug,本来想inline,但是没有inline成功,反而造成了重复定义,后者的可能性更大,因为这些超短函数不应该不被inline的,还是开了O2/O3优化的情况。
从这个例子,也说明了inline的正确使用方法。
那就是加static,在头文件中加 static inline,因为inline是建议性关键字,所以即使没有inline也不会重复定义,如果没有static就重复定义了,当然关于gcc,有强制inline的方法,
如果inline不放到头文件中呢,对于其他文件中的函数是没办法inline这个函数的,因为预处理的时候会把头文件中的内容插入放到当前文件,作为一个编译单元存在,如果在其他文件中,不会插入到当前文件,不在一个编译单元中,当然无法获取到代码,无法inline了,除非把多个文件一起编译,不知道这时候gcc会不会inline,或许有链接时优化,不知道会不会有相关处理,没深入的调查过。
超级短一两行代码的函数用static inline放在头文件中,开启优化,可以认为就是inline的。
总之就是知道原理,知道为什么加static,为什么放头文件中,inline和不inline会有什么影响,inline和在不在一个文件有什么不同,如何才能实现inline(至少要拿到代码才能inline)。