如何强制g ++内联函数?

tin*_*lyx 10 c++ haskell inline ffi ghci

在使用Haskell FFI到C/C++时,我最近遇到了C++内联函数的问题.也就是说,g ++并不真正内联声明的函数inline,并为它们生成符号.最终,当ghci尝试加载调用内联函数的目标文件时,这会生成链接器错误:

Loading object (static) solveeq.o ... done
Loading object (dynamic) /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++.so ... done
final link ... ghc: solveeq.o: unknown symbol `_ZN5Eigen8internal19throw_std_bad_allocEv'
Run Code Online (Sandbox Code Playgroud)

这里,_ZN5Eigen8internal19throw_std_bad_allocEvinline仅在标题的Eigen C++库中的函数,以某种方式被视为实函数并给出了链接器符号.solveeq.o是我的目标文件,它对该函数进行(间接)调用.环境是Ubuntu 12.04 64bit,ghc 7.4.1.

问题是这样的:我可以extern "C" 用来阻止C++为我自己的函数装饰函数名.但我不能/不应该更改其他人定义的C++标头(原因很明显).在我看来,编译器不应该首先为此内联定义创建一个函数来导致此错误.原因很简单.如果有问题的函数是真正内联的,我不会得到链接器错误.如果编译器变得聪明并决定为它创建一个真正的函数,我会得到这样的错误(或者我在其他地方读到的同一函数的多个定义).所以现在,编译/链接的正确性取决于编译器的情绪.

此外,我认为像这样的链接器问题实际上会破坏仅限标头的C++库(它们具有吸引力),因为现在无法使用它们进行导出extern "C".

这是c ++的设计问题还是仅仅是一个g ++问题?我的问题是,有没有办法阻止c ++编译器或g ++不内联内联函数?例如,是否有一个命令行选项?(修改源代码是不可能的,因为它们是库代码.)

另外,我很好奇C++ STL是如何处理这个问题的.它们也只是标题吗?

Die*_*ühl 3

函数是inline对编译器的一个提示,只要编译器认为合适,编译器就会很乐意忽略它。一些编译器会对声明inline但不是内联的函数发出警告,例如gcc 's -Winline,但禁用所有内联函数肯定是行不通的:有一些相当大的函数处理定义为模板的数据结构。所有隐式的模板代码都可以是内联的,并且这些模板的实例可以在多个翻译单元中发出。

与其试图为了与其他工具集成而硬塞 C++ 的行为,其他工具应该变得聪明并忽略它不感兴趣的符号。特别是,如果它对不需要的函数实例化并不真正感兴趣,那么它inline应该应该忽略这些。由于它们可以出现在多个翻译单元中,因此它们通常使用弱符号nm -po your-object-file.o当您在 UNIX 系统上使用时,grep对于您的工具所冒犯的符号,您应该会看到它们使用不同于普通符号的标记 ( T)。

另一种方法可能包括链接一个共享对象,该共享对象仅公开您实际想要公开的符号,并通过该工具使用该对象。也就是说,虽然我知道这种方法是可行的,但我自己还没有真正使用过。