I'm having problem compiling cpp file with C inline functions using g++11. Following is an example:
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);
}
Compile cmd
gcc -c c.c
g++ -c cpp.cpp
g++ c.o cpp.o
Problem: Link error. Multiple definitions of add.
The situation is using a C++ test framework to test a C code base. So I cannot modify the C code.
Platform is MSYS2/MinGW64, gcc 11.2.0. nm cpp.o gives the following:
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
I think your best option is to force the symbols to be emitted as weak in the C++ translation units by using file-level inline assembly:
As far as I can tell, GCC makes non-static inline function symbols weak out of the box on ELF targets, where it causes no issues (which also makes your original example compile just fine on Linux). For some reason, GCC doesn’t do the same on MinGW, even though the object format does have some support for weak symbols.
You will need to obtain a complete list of non-static inline functions in the C header to make this work. You should be able to generate one using
nm:You will obtain a file
weaksyms.h, which you can just include next to the C header. The order should not matter, nor should whether any of the symbols will actually end up in the C++ translation unit.I tested the above answer with Debian’s GCC 10 and binutils 2.37 targetting x86_64-w64-mingw32. Attempting to do the above with
#define inline __attribute__((__weak__)) inlinefor some reason does not work, and triggers a-Wattributeswarning instead.