When I've used older APIs, for example, the C sockets API on Unix, I always notice that people favor less-than (<
) over equal-to (==
) when comparing their bad return values.
int result = send(...);
if (result < 0) { perror("..."); }
In the cases I'm referring to, the return code is only ever positive, 0
, or -1
(with errno
set to the right value). So why not just check for an error using (result == -1)
instead of (result < 0)
?
I'm asking because I was wondering if it's done out of habit or if it's more efficient to use less-than? I was thinking about the fact that if you were comparing two uint64_t
s and you found the difference in the MSB, you woul开发者_JAVA百科dn't have to check the other 7 bytes, etc. I might be reaching with this logic though!
I think that this is neither for habit nor for efficiency. It is safer because you don't rely on a specific return code. Instead, you rely for the error code to be negative. For instance, strcmp
function returns "a negative value" when the first string is smaller than the second. On most implementations, it will return -1
, but the correct way to handle it is to check for < 0
OK, let's find out. This is GCC 4.6.1 on x86 with -O3
, and a
is of type int
:
if (a < 0)
:
movl 4(%esp), %eax
testl %eax, %eax
js .L4
if (a == -1)
:
cmpl $-1, 4(%esp)
je .L4
Here 4(%esp)
is the variable a
, and .L4
designates the jump destination of the conditional.
Update: As @yi_H suggests, now let's compare if (h() < 0)
and if (h() == -1)
, where int h();
is some function. We have:
< testl %eax, %eax
< js .L4
---
> cmpl $-1, %eax
> je .L4
This is done for robustness, not efficiency. If you only check for specific return values, such as -1, and the API is later modified to return -1 for one type of error and -2 for a different type of error, the code will no longer behave correctly. In most APIs a negative return value indicates error, so checking that the return value is negative to determine if an error has occurred is the robust solution.
To me, the only difference in your question is about specificity.
checking for < 0 is a very general test, that allows some sort of "future expansion".
any kind of performance difference would be negligible on today's hardware.
It's not a matter of less than versus equals. It's a matter of zero versus any other number. Comparison against zero (any comparison - equality, greater/equal, etc.) is generally cheaper than comparison against a specific non-zero value.
On some architectures, comparing against zero has a shorter, and hence slightly faster, implementation.
Because the error code can be any number less than 0 when it is an error and you would have multiple possible error codes that would let the programmer know what is the particular error. If you only checked for one case, that would not be sufficient.
精彩评论