如何强制g ++内联函数? [英] How to force g++ to inline functions?

查看:179
本文介绍了如何强制g ++内联函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have recently encountered an issue with C++ inline functions when using Haskell FFI to C/C++. Namely, g++ does not really inline functions that are declared inline, and generate symbols for them. Ultimately, this generates linker error when ghci tries to load an object file which calls the inline function:

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'

这里, _ZN5Eigen8internal19throw_std_bad_allocEv 是一个 inline 函数在头特有的Eigen C ++库不知何故被视为一个真正的函数,并给出一个链接器符号。 solveeq.o 是我的目标文件,使(间接)调用该函数。环境是Ubuntu 12.04 64位,ghc 7.4.1。

Here, _ZN5Eigen8internal19throw_std_bad_allocEv is an inline function in the header-only Eigen C++ library somehow being treated as a real function and given a linker symbol. solveeq.o is my object file which makes (indirect) calls to that function. The environment is Ubuntu 12.04 64bit, ghc 7.4.1.

问题是这样:我可以使用 externC以防止C ++装饰我自己的函数的函数名。但我不能/不应该改变由其他人定义的C ++头(因为显而易见的原因)。在我看来,编译器不应该为这个内联定义创建一个函数,首先引起这个错误。原因很简单。如果有问题的函数真正内联,我不会得到链接器错误。如果编译器变得聪明,并决定为它创建一个真正的函数,我得到这样的错误(或相同的函数的多个定义,我在其他地方阅读)。现在,编译/链接的正确性取决于编译器的心情。

The issue is this: I can use extern "C" to prevent C++ decoration of functions names for my own functions. But I cannot/shouldn't change the C++ headers defined by others (for obvious reasons). In my opinion, the compiler shouldn't create a function for this inline definition in the first place to cause this error. The reason is simple. If the function in question is truly inlined, I wouldn't get an linker error. If the compiler gets smart and decides to create a real function for it, I get errors like this (or multiple definitions of the same function, as I read elsewhere). So now, the correctness of compilation/linking depends on the mood of the compiler.

此外,我认为这样的链接器问题实际上会击败头文件C ++库呼吁他们的可移植性),因为现在他们不能使用 externC导出。

Also, I think linker issues like this practically defeats header-only C++ libraries (which are appealing for their portability) because now they can not be exported using extern "C".

问题c ++或者这只是一个g ++问题?我的问题是,有没有办法防止c ++编译器或g ++不内联函数?例如,有没有为此的命令行选项? (修改源代码是没有问题的,因为它们是库代码。)

Is this a design problem of c++ or is this just a g++ issue? My question is, is there a way to prevent c++ compilers or g++ from not inlining inline functions? For example, is there a command line option for this? (Modifying source codes is out of question as they are library codes.)

此外,我很好奇C ++ STL如何处理这个问题。

Also, I am curious how does the C++ STL deal with this issue. Are they also headers-only?

推荐答案

inline 的功能是提示编译器将无论何时看到合适的时候都会高兴地忽略。一些编译器对声明 inline 但不是内联的函数做警告,例如。 gcc -Winline ,但禁用所有内联函数必然是不可行的:有一些相当大的函数处理定义为模板的数据结构。所有隐式可能是内联的模板代码和这些模板的实例化可以在多个翻译单元中发出。

Functions being inline is a hint to the compilers which the compiler will happily ignore whenever it sees fit. Some compiler do warning about functions declared inline but not being inline, e.g. gcc's -Winline, but disabling all inline functions is bound to be non-workable: there are some rather sizable functions dealing with data structures defined as templates. All of the template code which is implicitly may be inline and instantiations of these template may be emitted in multiple translation units.

而不是试图以C ++的行为为目的与其他工具集成,其他工具应该智能化并忽略它不感兴趣的符号。特别是,如果它不是真正感兴趣的不必要的实例化 inline 函数,它应该忽略这些。由于它们可以出现在多个翻译单元中,他们通常使用弱符号。当您在UNIX系统上使用 nm -po your-object-file.o ,并且为您的工具使用 grep T )。

Instead of trying to shoehorn C++'s behavior for the purpose of integrating it with some other tool the other tool should smarten up and ignore symbols it isn't interested in. In particular, if it isn't really interested in unwanted instantiations of inline functions, it should just ignore these. Since they can appear in multiple translation units they normally use weak symbols. When you use nm -po your-object-file.o on a UNIX system and grep for the symbols your tool is offended by you should see them tagged using something different than normal symbols (T).

另一种方法可能包括:在链接一个共享对象,只公开了你实际想要公开的符号,并使用这个对象与工具。也就是说,虽然我知道这种方法是可行的,我自己没有真正使用它。

Another approach could consist in linking a shared object which only exposes the symbols you actually want to expose and use this object with the tool. That said, although I know that this approach is doable, I haven't really used it myself.

这篇关于如何强制g ++内联函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆