我使用libnet已经有一段时间了,我注意到有些函数的返回值是uint32_t
,据我所知,这是一种无符号类型。然而,在文档中,它说如果发生错误(这是一种有符号的类型),则返回-1。例如,参见libnet_get_ipaddr4
、libnet_get_prand
。
然而,我已经毫无问题地处理了这样的功能:
if ((src_ip_addr = libnet_get_ipaddr4(l)) == -1) {
/* treat the failure*/
}
我假设在-1和返回值之间进行比较,-1被解释为无符号int,返回值取相同的值;比较是正确的。
尽管这显然有效,但我的问题是:这有意义吗?为什么作为一名程序员,我应该如何检查返回值以了解是否发生了错误?上面显示的代码片段是否正确?
引用C99标准草案,6.2.5.9:
涉及无符号操作数的计算永远不会溢出,因为无法由生成的无符号整数类型表示的结果是降模-比最大值大一的数字由结果类型表示。
So-1自动转换为UINT32_MAX
。
警告:处理超出范围的值对于签名的类型来说不太好。请参阅此处和此处了解各种复杂情况。
6.5.9规定,对于相等运算符,
如果两个操作数都具有算术类型,则通常的算术转换为执行。
6.3.1.8描述了这些转换:
[…]否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的秩,然后是具有带符号整数类型转换为带无符号的操作数的类型整数类型。[…]
(对于返回有符号类型的函数,您可以在标准中查找返回-1的类似理由,但它基本上是相同的参数,所以我不会麻烦。)
换句话说,是的,这是完全正确的。