Nested if statements and “&&” operator

2019-02-17 00:57发布

问题:

if(a() && b() && c() && d())
   doSomething();


if(a())
   if(b()) 
      if(c())
         if(d())
            doSomething();

Is there "any" performance difference between these two?

For example, in a situation that a() turns 0, will it keep running b(), c() and d() in the first if statement? Or will it work same as the second nested if statement?

回答1:

They're exactly identical.

To test this yourself, run gcc -S test.c (presuming that this is where you've put your source) and observe the contents of test.s.


Here's how the nested-if approach compiles in gcc 4.8.1 with default options (annotated with comments):

main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0, %eax
    call    A                        # try to call A
    testl   %eax, %eax               # look at its return value
    je  .L3                          # short-circuit if it returned 0
    movl    $0, %eax                 # ...repeat for B, et al.
    call    B
    testl   %eax, %eax
    je  .L3
    movl    $0, %eax
    call    C
    testl   %eax, %eax
    je  .L3
    movl    $0, %eax
    call    D
    testl   %eax, %eax
    je  .L3
    movl    $0, %eax
    call    doSomething
.L3:
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc

Here's how the && approach compiles:

main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0, %eax
    call    A                           # try to call A
    testl   %eax, %eax                  # look at its return value
    je  .L3                             # short-circuit if it returned 0
    movl    $0, %eax                    # ...repeat for B, et al.
    call    B
    testl   %eax, %eax
    je  .L3
    movl    $0, %eax
    call    C
    testl   %eax, %eax
    je  .L3
    movl    $0, %eax
    call    D
    testl   %eax, %eax
    je  .L3
    movl    $0, %eax
    call    doSomething
.L3:
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc