小于比。 等效于效率C / C ++

当我使用旧的API,例如Unix上的C套接字API时,我总是注意到人们在比较它们的错误返回值时更喜欢小于( < )而不是等于( == )。

 int result = send(...); if (result < 0) { perror("..."); } 

在我所指的情况下,返回代码只是正数, 0-1 (将errno设置为正确的值)。 那么为什么不使用(result == -1)而不是(result < 0)来检查错误?

我问,因为我想知道这是出于习惯还是使用少于?的效率更高? 我正在考虑这样一个事实:如果你比较两个uint64_t并且你发现了MSB的差异,你就不必检查其他7个字节,等等。我可能会接触到这个逻辑!

我认为这既不是习惯也不是效率。 它更安全,因为您不依赖于特定的返回代码。 相反,您依赖于错误代码是否定的。 例如,当第一个字符串小于第二个字符串时, strcmp函数返回“负值”。 在大多数实现中,它将返回-1 ,但处理它的正确方法是检查< 0

好的,我们来看看。 这是x86上带有-O3 GCC 4.6.1, aint类型:

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(); 是一些function。 我们有:

 < testl %eax, %eax < js .L4 --- > cmpl $-1, %eax > je .L4 

这样做是为了坚固,而不是效率。 如果仅检查特定的返回值(例如-1),并且稍后修改API以针对一种类型的错误返回-1,针对不同类型的错误返回-2,则代码将不再正常运行。 在大多数API中,负返回值表示错误,因此检查返回值是否为负值以确定是否发生了错误是强大的解决方案。

对我而言,你问题的唯一区别在于特异性

检查<0是一个非常通用的测试,允许某种“未来扩展”。

在今天的硬件上,任何类型的性能差异都可以忽略不计。

与平等相比,这不是一个问题。 与任何其他数字相比,这是零问题。 与零的比较(任何比较 – 相等,更大/相等等)通常比与特定非零值的比较更便宜。

在某些体系结构中,与零进行比较的实现更短,因此更快。

因为错误代码在出错时可以是小于0的任何数字,并且您将有多个可能的错误代码,这将使程序员知道什么是特定错误。 如果您只检查了一个案例,那就不够了。