Reputation: 39254
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 wouldn't have to check the other 7 bytes, etc. I might be reaching with this logic though!
Upvotes: 16
Views: 9441
Reputation: 215193
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.
Upvotes: 2
Reputation: 476970
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
Upvotes: 11
Reputation: 25116
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.
Upvotes: 2
Reputation:
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.
Upvotes: 1
Reputation: 1191
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.
Upvotes: 6
Reputation: 28829
On some architectures, comparing against zero has a shorter, and hence slightly faster, implementation.
Upvotes: 1
Reputation: 132984
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
Upvotes: 16