空的内联函数到底发生了什么? [英] What exactly happens to empty inline functions?

查看:89
本文介绍了空的内联函数到底发生了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写代码(使用GCC 4.7.2),在测试阶段,我在代码的无数位置中过多地记录了东西.这些日志记录应在发行版二进制文件中消失.

I'm writing code (using GCC 4.7.2), where I'm excessively logging stuff during the testing phase in countless positions of the code. These loggings should disappear on the release binary.

我正在通过像void log(std::string msg);这样的函数进行日志记录.由于这些函数调用很多,并通过整个代码分布在许多文件中,所以我有一个想法,使它成为一个内联函数,只为发布二进制文件提供一个空的正文.

I'm doing the logging via a function just like void log(std::string msg);. As these function calls are many and distributed via the whole code in many files, I had the idea to make it an inline function and just give it an empty body for the release binary.

我的问题不是:编译器如何处理它?二进制文件是否只包含没有功能的其余代码,是否包含nop或其他内容?我可以通过清空内联日志记录功能来完全消除二进制文件中的日志记录代码吗?

No my question is: what does the compiler do with it? Does the binary just contain the rest of the code without the function, does it contain a nop, or anything else? Could I eliminate the logging code from the binary completely by emptying the inline logging function?

我不仅对解决问题的答案感兴趣,而且对编译器的行为本身也很好奇.

I'm not only interested in an answer to solve the problem but I'm also curious about the compiler's behaviour itself.

推荐答案

如果要在调试和发行版之间使用不同的代码,那么这是预处理器的理想用例:

If you want different code between debug and release, then that's an ideal use case for the preprocessor:

#ifdef NDEBUG
#define log(ignored)
#endif

然后,您就不用再依赖编译器了.您可以确保只有调试版本才会有额外的调用.这也是assert的工作方式.

Then you're not leaving anything up to the compiler. You're guaranteed that only the debug version will have the extra calls. This is how assert works, too.

请注意,这也会删除参数计算.例如,如果您有log(get_msg()),则宏方法也将调用降为get_msg().这可能是合乎需要的,但您需要意识到这一点.

Note that this will also drop the parameter computation. For example, if you have log(get_msg()) then the macro method will drop the call to get_msg() as well. This is probably desirable, but you need to be aware of it.

至于inline,这完全取决于编译器. inline关键字本身仅是一个提示,它不要求编译器执行任何操作.编译器根据是否内联特定函数(包括未标记为inline的内联函数)执行自己的优化计算.这通常意味着足够高的优化级别(即-O3),并且内联函数的主体在该特定编译单元中可见.例如,如果编译器仅看到一个声明,但(可能为空)函数体位于另一个.cpp文件中,则它不能内联.但是,是的,如果编译器确定没有副作用,那么可以自由地使整个函数消失.

As for inline, that's entirely up to the compiler. The inline keyword itself is only a hint, it does not obligate the compiler to do anything. The compiler performs its own optimization calculations on whether or not to inline a particular function (that includes inlining functions not marked inline). That typically means a sufficiently high optimization level (i.e. -O3), and that the body of the inline function is visible in that particular compilation unit. For example, if the compiler only sees a declaration but the (maybe empty) function body is in a different .cpp file, then it cannot inline. But yes, if the compiler determines that there are no side effects, it is free to make the whole function disappear.

但是同样,当预处理器提供这种干净且广泛使用的解决方案时,没有理由依赖于此.

But again, there's no reason to depend on that when the preprocessor offers such a clean and widely used solution.

这篇关于空的内联函数到底发生了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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