如果返回相同的内容,C编译器是否合并if语句?

如果返回相同的内容,C编译器是否合并if语句?,c,if-statement,compiler-optimization,c99,C,If Statement,Compiler Optimization,C99,我试图理解编译器如何优化返回相同值的两个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; } 虽然注释强调此行为依赖于编译器实现,但查看特定编译器有助于理解这

我试图理解编译器如何优化返回相同值的两个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
指令进行两次比较


如果愿意,您可以编写具有这种行为的编译器

为什么不检查呢?C将保证等价的求值和结果,因为它保证短路布尔求值。编译器是否会生成相同的代码完全取决于实现。