正如 Keith Thompson 指出的那样,两者不相同。例如,如果a 和b 是无符号的,则a-b 始终为非负数,从而使语句等效于if(a != b)。
反正我做了一个不切实际的测试:
int main() {
volatile int a, b;
if(a-b>=0)
printf("a");
if(a>b)
printf("b");
return 0;
}
用-O3 编译它。这是反汇编:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
subq $16, %rsp
movl -4(%rbp), %eax
subl -8(%rbp), %eax
testl %eax, %eax
jle LBB0_2
## BB#1:
movl $97, %edi
callq _putchar
LBB0_2:
movl -4(%rbp), %eax
cmpl -8(%rbp), %eax
jle LBB0_4
## BB#3:
movl $98, %edi
callq _putchar
LBB0_4:
xorl %eax, %eax
addq $16, %rsp
popq %rbp
ret
在-O3,a-b>0 仍在使用一条额外的指令。
即使你用 ARM 编译器编译,也有额外的指令:
push {lr}
sub sp, sp, #12
ldr r2, [sp, #0]
ldr r3, [sp, #4]
subs r3, r2, r3
cmp r3, #0
ble .L2
movs r0, #97
bl putchar(PLT)
.L2:
ldr r2, [sp, #0]
ldr r3, [sp, #4]
cmp r2, r3
ble .L3
movs r0, #98
bl putchar(PLT)
.L3:
movs r0, #0
add sp, sp, #12
pop {pc}
请注意,(1)volatile 是不现实的,除非您正在处理例如硬件寄存器或线程共享内存,以及 (2) 实践中的差异甚至无法衡量。
由于两者在某些情况下具有不同的语义,写出正确的。以后担心优化!