我试图了解编译器将如何优化两个返回相同值的if语句。在函数顶部考虑以下代码:
if (some_ptr == NULL) {
return -1;
}
if (some_other_ptr == NULL) {
return -1;
}
将两个if语句合并为一项检查,该检查等同于:
if (some_ptr == NULL || some_other_ptr == NULL) {
return -1;
}
最佳答案
尽管评论强调此行为取决于编译器实现,但是查看特定的编译器有助于理解这一点。
使用测试程序:
int main(int argc, char *argv[]) {
srand(time(NULL));
char *some_ptr = (char *) rand();
char *some_other_ptr = (char *) rand();
if (some_ptr == NULL) {
return -1;
}
if (some_other_ptr == NULL) {
return -1;
}
return 0;
}
在运行OS X的笔记本电脑上使用clang且无优化(-O0标志),程序集输出紧跟输入代码,没有快捷方式。
movslq %eax, %rcx
movq %rcx, -32(%rbp)
cmpq $0, -24(%rbp)
jne LBB0_2
## BB#1:
movl $-1, -4(%rbp)
jmp LBB0_5
LBB0_2:
cmpq $0, -32(%rbp)
jne LBB0_4
## BB#3:
movl $-1, -4(%rbp)
jmp LBB0_5
LBB0_4:
movl $0, -4(%rbp)
LBB0_5:
movl -4(%rbp), %eax
addq $32, %rsp
popq %rbp
retq
.cfi_endproc
但是以最高的优化程度(-O3标志)进行编译会导致一些不同的代码。
movl %eax, %ecx
movl $-1, %eax
testl %ebx, %ebx
je LBB0_2
## BB#1:
cmpl $1, %ecx
sbbl %eax, %eax
LBB0_2:
addq $8, %rsp
popq %rbx
popq %rbp
retq
.cfi_endprocemphasized text
无论哪种情况,在我的clang版本中,编译器都不会将两个布尔结果一起使用,甚至在优化后的代码中,也将通过
testl
和cmpl
指令进行两次比较。如果愿意,您可以编写具有这种行为的编译器!