【发布时间】:2011-02-10 08:16:38
【问题描述】:
我们在一个通用实用程序库中有一个用于指示错误的宏,如下所示:
#define OurMacro( condition ) \
if( condition ) { \
} else { \
CallExternalFunctionThatWillThrowAnException( parametersListHere ); \
} \
我所说的parametersListHere 是由编译器在每次宏扩展时填充的常量和宏的逗号分隔列表。
该函数调用始终解析为调用 - 函数实现不会暴露给编译器。该函数有六个参数,在调试配置中它们都有有意义的值,而在发布配置中只有两个具有有意义的值,其他的则传递相同的默认值。
通常条件会成立,所以我不关心调用有多快,我只关心代码膨胀。使用 6 个参数调用该函数需要 7 个 x86 指令(6 个 pushes 和一个 call),如果将函数签名更改为只有两个参数,显然可以避免其中的 4 个 pushes - 这可以是通过引入以这种方式实现的中间“门”函数来完成,它的实现对编译器是不可见的。
我需要估计我是否应该坚持这种改变。到目前为止,我预计的主要改进是减少参数数量将在每次调用时减少 4 条指令,这意味着围绕宏扩展的代码将变得更小,编译器将更有可能内联它并进一步优化发出的代码。
如果不实际尝试并重新编译我们所有的代码并仔细分析发出的代码,我该如何估算?每次我读到inline 时,都会有一条语句表明编译器决定是否内联函数。
我能看到一些关于函数内部如何影响编译器内联决策的确切规则吗?
【问题讨论】:
-
有什么原因你没有
#ifdef NDEBUG开关的两个不同功能? -
@Matthieu M.:原始函数可能已经从一些我不知道的代码中调用。无论如何,使用新函数或通过更改现有函数签名,我可以得到完全相同的结果,所以我选择哪种方式并不重要。
标签: c++ visual-c++ optimization compiler-construction inline