为何GCC编译的foobar函数汇编未显式实现条件判断逻辑?
GCC编译优化疑问:为何省略返回值比较逻辑?
原C++代码
int foo(int); int bar(int); int foobar(int i) { int a = foo(i); int b = bar(i); return a == b ? a : b; };
GCC trunk编译后的汇编代码
foobar(int): push rbx mov ebx, edi call foo(int) mov edi, ebx pop rbx jmp bar(int)
问题描述
该翻译单元(TU)无法预知输入参数i的值,也无法确定foo和bar的返回值,因此无法判断a == b是否成立,理论上必须比较两者的返回值来决定返回结果,但在汇编中未看到相关逻辑,请问遗漏了什么?
解答
这是GCC识别出逻辑等价性后做出的合理优化,核心原因如下:
- 原代码中的
return a == b ? a : b;逻辑等价于直接返回b:当a == b时,返回a也就是b;当a != b时,返回b。无论哪种情况,最终返回的都是bar(i)的结果。 - 编译器必须保留对
foo(i)的调用:因为foo是外部函数,编译器无法确定它是否存在副作用(比如修改全局变量、执行IO操作等),所以不能省略这个调用。 - 汇编中的
jmp bar(int)利用了x86-64架构的函数返回规则:int类型的返回值会存在eax寄存器中,直接跳转到bar执行后,bar的返回值会直接作为foobar的返回值,省去了冗余的比较、分支和寄存器移动操作。
所以汇编中没有比较逻辑是完全合理的,因为从逻辑上根本不需要比较,直接返回bar的结果即可。
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

