如果 return 相同,C 编译器会合并 if 语句吗?
Does the C compiler combine if statements if they return the same thing?
我试图了解编译器如何优化 return 具有相同值的两个 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;
}
在我的笔记本电脑上使用 clang 运行 OS X,没有优化(-O0 标志),汇编输出紧跟输入代码,没有快捷方式。
movslq %eax, %rcx
movq %rcx, -32(%rbp)
cmpq [=11=], -24(%rbp)
jne LBB0_2
## BB#1:
movl $-1, -4(%rbp)
jmp LBB0_5
LBB0_2:
cmpq [=11=], -32(%rbp)
jne LBB0_4
## BB#3:
movl $-1, -4(%rbp)
jmp LBB0_5
LBB0_4:
movl [=11=], -4(%rbp)
LBB0_5:
movl -4(%rbp), %eax
addq , %rsp
popq %rbp
retq
.cfi_endproc
但是使用最高优化(-O3 标志)进行编译会产生一些不同的代码。
movl %eax, %ecx
movl $-1, %eax
testl %ebx, %ebx
je LBB0_2
## BB#1:
cmpl , %ecx
sbbl %eax, %eax
LBB0_2:
addq , %rsp
popq %rbx
popq %rbp
retq
.cfi_endprocemphasized text
在任何一种情况下,对于我的 clang 版本,编译器都不会将两个布尔结果放在一起,即使在优化代码中,也会通过 testl
和cmpl
说明。
如果你愿意,你可以编写一个具有这种行为的编译器!
我试图了解编译器如何优化 return 具有相同值的两个 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;
}
在我的笔记本电脑上使用 clang 运行 OS X,没有优化(-O0 标志),汇编输出紧跟输入代码,没有快捷方式。
movslq %eax, %rcx
movq %rcx, -32(%rbp)
cmpq [=11=], -24(%rbp)
jne LBB0_2
## BB#1:
movl $-1, -4(%rbp)
jmp LBB0_5
LBB0_2:
cmpq [=11=], -32(%rbp)
jne LBB0_4
## BB#3:
movl $-1, -4(%rbp)
jmp LBB0_5
LBB0_4:
movl [=11=], -4(%rbp)
LBB0_5:
movl -4(%rbp), %eax
addq , %rsp
popq %rbp
retq
.cfi_endproc
但是使用最高优化(-O3 标志)进行编译会产生一些不同的代码。
movl %eax, %ecx
movl $-1, %eax
testl %ebx, %ebx
je LBB0_2
## BB#1:
cmpl , %ecx
sbbl %eax, %eax
LBB0_2:
addq , %rsp
popq %rbx
popq %rbp
retq
.cfi_endprocemphasized text
在任何一种情况下,对于我的 clang 版本,编译器都不会将两个布尔结果放在一起,即使在优化代码中,也会通过 testl
和cmpl
说明。
如果你愿意,你可以编写一个具有这种行为的编译器!