为什么 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_tlong 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中,int0转换为size_t。这不会改变价值;转换结果为0,类型为size_t。然后比较两个size_t值4,294,967,293和0。由于4,294,967,293不小于0,所以比较结果为false(零)。

(int)var < 0中,size_tvar转换为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.

比较时发生