调用处重复的返回值条件检查能否被编译器优化?是否受inline属性影响?
问题解答
重复校验的优化可行性
你描述的这类重复返回值校验是可以被编译器优化掉的,前提是编译调用点时编译器能看到函数的完整实现,且开启了足够的优化等级(通常O2及以上优化就会触发冗余代码消除)。
你给出的示例中,try_get的返回值只有两种可能:非空的静态变量地址、空指针nullptr,和调用处if(p)的判断逻辑完全等价。只要编译器能拿到try_get的完整实现,就能识别出两次检查的冗余性,直接删除调用处的重复判断。
你不需要完全读懂汇编也可以简单验证优化结果:只要看生成的汇编代码中,比较指令(通常是
cmp)和对应的条件跳转指令的数量,优化完成的版本只会保留一次判断rand()%2结果的逻辑,不会出现第二次判断指针是否为0的多余操作。
inline关键字对优化的影响
inline对该优化的影响核心取决于是否让函数体对调用点可见:
- 如果函数和调用逻辑在同一个编译单元(同一个cpp文件)内:即使你不手动加inline关键字,开启优化后编译器也会自动对小体积函数做内联展开,展开后就能识别到冗余检查并删除,此时手动加不加inline几乎没有区别。
- 如果函数定义在头文件中,需要被多个编译单元调用:如果不加inline,函数只能在头文件放声明、实现放在单独的cpp中,其他编译单元编译调用点时看不到函数的实现逻辑,就无法判断两次检查是否冗余,也就没法做优化;如果加了inline,函数体可以直接放在头文件中,所有调用的编译单元都能看到完整实现,就具备了优化的前提条件。
如果函数实现位于外部动态库、或者编译器无法在编译期拿到函数的完整逻辑,不管加不加inline,都无法完成这类冗余检查消除的优化。
内容的提问来源于stack exchange,提问作者Zebrafish
相关产品推荐
相关产品推荐

