当我使用较旧的API时,例如Unix上的C套接字API,我总是会注意到人们在比较时喜欢小于(<
)而不是等于(==
)他们糟糕的回报价值。
int result = send(...);
if (result < 0) { perror("..."); }
在我所指的情况下,返回代码只有正数,0
或-1
(errno
设置为正确的值)。那么为什么不使用(result == -1)
而不是(result < 0)
检查错误?
我在问,因为我想知道这是出于习惯还是使用少于?的效率更高?我在考虑这样一个事实:如果你比较两个uint64_t
并且你发现了MSB的差异,你就不必检查其他7个字节,等等。我可能会接触到这个逻辑!
答案 0 :(得分:15)
我认为这既不是习惯也不是效率。它更安全,因为您不依赖于特定的返回代码。相反,您依赖于错误代码是否定的。例如,当第一个字符串小于第二个字符串时,strcmp
函数返回“负值”。在大多数实现中,它将返回-1
,但处理它的正确方法是检查< 0
答案 1 :(得分:7)
好的,我们来看看。这是x86上的GCC 4.6.1 -O3
,而a
的类型为int
:
if (a < 0)
:
movl 4(%esp), %eax
testl %eax, %eax
js .L4
if (a == -1)
:
cmpl $-1, 4(%esp)
je .L4
此处4(%esp)
是变量a
,.L4
指定条件的跳转目的地。
更新:正如@yi_H建议的那样,现在让我们比较if (h() < 0)
和if (h() == -1)
,其中int h();
是一些功能。我们有:
< testl %eax, %eax
< js .L4
---
> cmpl $-1, %eax
> je .L4
答案 2 :(得分:4)
这是为了稳健而非效率。如果您只检查特定的返回值(例如-1),并且稍后修改API以针对一种类型的错误返回-1,针对不同类型的错误返回-2,则代码将不再正常运行。在大多数API中,负返回值表示错误,因此检查返回值是否为负值以确定是否发生了错误是强大的解决方案。
答案 3 :(得分:2)
对我而言,您问题的唯一区别在于特异性。
检查&lt; 0是一个非常通用的测试,允许某种“未来扩展”。
今天的硬件上任何类型的性能差异都可以忽略不计。
答案 4 :(得分:2)
与平等相比,这不是一个问题。与任何其他数字相比,这是零问题。与零比较(任何比较 - 相等,更大/相等等)通常比与特定非零值的比较便宜。
答案 5 :(得分:1)
在某些体系结构中,与零进行比较的实现时间更短,因此速度更快。
答案 6 :(得分:1)
因为错误代码在错误时可以是小于0的任何数字,并且您将有多个可能的错误代码,这将使程序员知道什么是特定错误。如果您只检查了一个案例,那就不够了。