为什么 size_t 变量,int 常量比较不能正常工作,而 off_t 变量工作正常?
why size_t variable, int constant comparison doesn't work properly while off_t variable works fine?
我试图比较 size_t
(ubuntu 的long int
类型)变量与 int
常量 0
但结果无法正常工作。但是 off_t
变量工作正常。
size_t var = -3;
if(var < 0)
putchar('X');
else
putchar('Y');
// Y
但是当我将 var
转换为 int
时,它按预期工作。
size_t var = -3;
if((int)var < 0)
putchar('X');
else
putchar('Y');
// X
但是 off_t
(long int
在我的 ubuntu 上也是如此)无需转换即可正常工作。
off_t var2 = -3;
if(var2 < 0)
putchar('X');
else
putchar('Y');
// X
你能解释一下吗?谢谢。
size_t
类型是无符号类型。因此,当您尝试将值 -3 分配给它时,该值会转换为非常大的正值。这就是第一种情况的条件为假的原因。
在第二种情况下,当将 var
转换为 int
时,分配的值(即之前的非常大的正值)超出了 int
的范围,因此它以实现定义的方式进行转换。在大多数实现中,这将导致值被转换为 -3,因此条件将为真。
类型 off_t
是有符号类型,因此它能够存储值 -3,因此比较按预期进行。
size_t
是无符号整数类型,根据 C 2018 7.19 2。为了说明,在这个答案中我将其视为 32 位,最大值为 4,294,967,295 (232−1),我将int
视为32位,最小值为-2,147,483,648,最大值为+2,147,483,647。整数类型的宽度在 C 实现之间可能不同。
对于size_t var = -3;
,-3被转换为无符号类型。此转换换行模 4,294,967,296 (232),因此 4,294,967,293 存储在 var
.
中
在var < 0
中,int
0
转换为size_t
。这不会改变价值;转换结果为0,类型为size_t
。然后比较两个size_t
值4,294,967,293和0。由于4,294,967,293不小于0,所以比较结果为false(零)。
在(int)var < 0
中,size_t
var
转换为int
。由于 4,294,967,293 大于我们的 int
可以表示的,因此在 C 2018 6.3.1.3 3 中指定了转换,表示结果为 implementation-defined。在常见的 C 实现中,它包装模 232,在这种情况下,此转换产生我们从 −3 开始的值。然后比较 int
值 −3 和 0。由于−3小于0,所以比较结果为真(一)。
off_t
是有符号整数类型。 (这是Unix或其他implementation-defined类型,不是C标准的一部分。)由于它能够表示-3,所以用-3初始化时不会发生值变化,并且值不会发生变化与 0
.
比较时发生
我试图比较 size_t
(ubuntu 的long int
类型)变量与 int
常量 0
但结果无法正常工作。但是 off_t
变量工作正常。
size_t var = -3;
if(var < 0)
putchar('X');
else
putchar('Y');
// Y
但是当我将 var
转换为 int
时,它按预期工作。
size_t var = -3;
if((int)var < 0)
putchar('X');
else
putchar('Y');
// X
但是 off_t
(long int
在我的 ubuntu 上也是如此)无需转换即可正常工作。
off_t var2 = -3;
if(var2 < 0)
putchar('X');
else
putchar('Y');
// X
你能解释一下吗?谢谢。
size_t
类型是无符号类型。因此,当您尝试将值 -3 分配给它时,该值会转换为非常大的正值。这就是第一种情况的条件为假的原因。
在第二种情况下,当将 var
转换为 int
时,分配的值(即之前的非常大的正值)超出了 int
的范围,因此它以实现定义的方式进行转换。在大多数实现中,这将导致值被转换为 -3,因此条件将为真。
类型 off_t
是有符号类型,因此它能够存储值 -3,因此比较按预期进行。
size_t
是无符号整数类型,根据 C 2018 7.19 2。为了说明,在这个答案中我将其视为 32 位,最大值为 4,294,967,295 (232−1),我将int
视为32位,最小值为-2,147,483,648,最大值为+2,147,483,647。整数类型的宽度在 C 实现之间可能不同。
对于size_t var = -3;
,-3被转换为无符号类型。此转换换行模 4,294,967,296 (232),因此 4,294,967,293 存储在 var
.
在var < 0
中,int
0
转换为size_t
。这不会改变价值;转换结果为0,类型为size_t
。然后比较两个size_t
值4,294,967,293和0。由于4,294,967,293不小于0,所以比较结果为false(零)。
在(int)var < 0
中,size_t
var
转换为int
。由于 4,294,967,293 大于我们的 int
可以表示的,因此在 C 2018 6.3.1.3 3 中指定了转换,表示结果为 implementation-defined。在常见的 C 实现中,它包装模 232,在这种情况下,此转换产生我们从 −3 开始的值。然后比较 int
值 −3 和 0。由于−3小于0,所以比较结果为真(一)。
off_t
是有符号整数类型。 (这是Unix或其他implementation-defined类型,不是C标准的一部分。)由于它能够表示-3,所以用-3初始化时不会发生值变化,并且值不会发生变化与 0
.