- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写代码(使用 GCC 4.7.2),在测试阶段我在代码的无数位置记录了过多的内容。这些日志记录应该会在发布的二进制文件中消失。
我正在通过类似 void log(std::string msg);
的函数进行日志记录。由于这些函数调用很多,并且通过整个代码分布在许多文件中,所以我想将其设为内联函数,并为其提供一个空主体以用于发布二进制文件。
不,我的问题是:编译器用它做什么?二进制文件是否仅包含没有函数的其余代码,是否包含 nop
或其他任何内容?我可以通过清空内联日志记录功能来完全消除二进制文件中的日志记录代码吗?
我不仅对解决问题的答案感兴趣,而且对编译器的行为本身也很好奇。
最佳答案
如果您想要在调试和发布之间使用不同的代码,那么这是预处理器的理想用例:
#ifdef NDEBUG
#define log(ignored)
#endif
那么您就不会将任何东西留给编译器。你保证只有调试版本会有额外的调用。这也是 assert
的工作方式。
请注意,这也会放弃参数计算。例如,如果您有 log(get_msg())
,那么宏方法也会放弃对 get_msg()
的调用。这可能是可取的,但您需要意识到这一点。
至于inline
,这完全取决于编译器。 inline
关键字本身只是一个提示,它并不强制编译器做任何事情。编译器对是否内联特定函数(包括未标记为 inline
的内联函数)执行自己的优化计算。这通常意味着足够高的优化级别(即 -O3),并且内联函数的主体在该特定编译单元中可见。例如,如果编译器只看到声明但(可能是空的)函数体在不同的 .cpp 文件中,则它不能内联。但是,是的,如果编译器确定没有副作用,它可以自由地让整个函数消失。
但同样,当预处理器提供如此干净且广泛使用的解决方案时,没有理由依赖它。
关于c++ - 空内联函数到底发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21657455/
这对你们来说可能很简单,但由于我是java新手,所以我想知道实际上什么是 接下来的部分会发生什么? if (args.length > 0) { file = args[0]; } publi
在我的 View Controller 中,我将 UITapGestureRecognizer 添加到 self.view。我在 self.view 之上添加了一个小 View 。当我点击小 View
我今天尝试从 Obj-C 开始并转到 Swift,我正在阅读文档。我试图在 Swift 中创建一个简单的 IBOutlet,但它不断给我这些错误。 View Controller 没有初始化器 req
我正在尝试使用 VIM 完成(字典和当前缓冲区),但我遇到了问题?和 !在方法名称的末尾。我能以某种方式向 vim 解释方法名称(基本上是单词)最后只能有它,而且只有一个,即 method_name
我是一名优秀的程序员,十分优秀!