如何使用g++11编译带有内联函数的C头



我在使用g++11编译带有C内联函数的cpp文件时遇到问题。以下是一个例子:

c.h:

#ifndef C_H
#define C_H
#ifdef __cplusplus
extern "C" {
#endif
inline int add(int a,int b){return a+b;}
#ifdef __cplusplus
}
#endif
#endif

c.c

#include "c.h"
extern inline int add(int a,int b);

cpp.cpp:

#include "c.h"
int main(){
return add(1,2);
}

编译cmd

gcc -c c.c
g++ -c cpp.cpp
g++ c.o cpp.o

问题:链接错误。添加的多个定义。

这种情况是使用C++测试框架来测试C代码库。所以我不能修改C代码。

平台为MSYS2/MinGW64,gcc 11.2.0。nm cpp.o给出以下内容:

0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 p .pdata
0000000000000000 p .pdata$add
0000000000000000 r .rdata$zzz
0000000000000000 t .text
0000000000000000 t .text$add
0000000000000000 r .xdata
0000000000000000 r .xdata$add
U __main
0000000000000000 T add
0000000000000000 T main

我认为最好的选择是通过使用文件级内联汇编:来强制符号在C++翻译单元中以弱的形式发出

__asm__(".weak add");
#include "c.h"

据我所知,GCC使非静态内联函数符号在ELF目标上开箱即用,不会引起任何问题(这也使您的原始示例在Linux上编译得很好(。出于某种原因,GCC在MinGW上没有做同样的事情,尽管对象格式确实支持弱符号。

您需要在C头中获得一个完整的非静态内联函数列表才能实现这一点。您应该能够使用nm:生成一个

g++ -c -x c++ c.h -o /tmp/syms.o -Dinline='__attribute__((__used__)) inline' &&
nm -g -f just-symbols /tmp/syms.o |
awk '{ print "X(" $0 ");" }' |
gcc -E -P - -D'X(a)=__asm__(".weak " #a)' -o weaksyms.h

您将获得一个文件weaksyms.h,您可以将其包含在C标头旁边。顺序应该无关紧要,是否有任何符号最终会出现在C++翻译单元中也不重要。

我用Debian的GCC 10和binutils 2.37测试了上面的答案,目标是x86_64-w64-mingw32。由于某种原因,尝试对#define inline __attribute__((__weak__)) inline执行上述操作不起作用,而是触发-Wattributes警告。

相关内容

  • 没有找到相关文章

最新更新