将off_t和ssize_t与其他类型进行比较

我是C的新手,最近因数据类型和内存分配不匹配而遇到了一些麻烦。 我正在编写一个非常简单的程序来计算使用Linux系统调用读取的文件的xor校验和。

我的问题是:在将off_tssize_tlongint进行比较时,是否需要关注不可预测的结果?

例如:

long i; for(i = 0; i < fileStat.st_size; i++) { // do stuff } 

并且:

 ssize_t i; for(i = 0; i < fileStat.st_size; i++) { // do stuff } 

比较相同签名但不同大小的类型相互作用,因为较小的类型扩展到较大的类型。 比较不同签名的类型是有问题的,因为如果签名类型不大于无符号类型且签名数字为负,则可能会得到错误的结果。 最好确保签名的数字最初不是负数:

 signed_t a; unsigned_t b; /* instead of */ if (a < b) /* ... */ /* use */ if (a < 0 || a < b) /* ... */ 

C标准规定long类型足够大以表示常量LONG_MAX ,其必须至少为2147483647(2 31 -1)。 如果我们将此下限作为LONG_MAX的值,那么它可能不够大。 毕竟,它不到2 GiB。

ssize_t不在C标准中,但在POSIX标准中定义。 它必须足够大以表示常量SSIZE_MAX ,其必须至少为32767(2 15 -1)。 也不要依赖这种类型。

在我的机器上, longssize_t都是4个字节。 您可以使用sizeof运算符sizeofvalidation大小。 您可能会得到不同的结果。 如果您希望程序可移植,请不要依赖特定于实现的内容。

最后,如果你真的不想使用那些typedef,我建议使用unsigned long long类型。 它足够大以表示常量ULLONG_MAX ,其必须至少为18446744073709551615(2 64 -1)。

另见: http : //pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html

有关有符号整数和无符号整数(以及其他算术运算)之间比较的警告源于两个不同类型的操作数与运算符组合时发生的隐式转换。

在Gimpel的PC-Lint工具附带的手册中有一个很好的章节。

阅读可用的C标准文件,特别是“整数促销”是有帮助的。

例如,见http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf(C99 ) – 第6.3.1节“算术操作数”

特别是,“如果int可以表示原始类型的所有值,则该值将转换为int;否则,将转换为unsigned int”

因此,在这样的上下文中,“-1”将被转换为二进制全1 [依赖于实现]作为无符号数 – 可能给不谨慎的人带来惊人的结果。 例如,无符号整数除以整数“-1”将给出零。

答案是在算术之前将无符号转换为有符号值。

请注意,sizeof()返回无符号值。