减去2 size_t的类型是什么?

net*_*cat 21 c size-t

C中应该使用哪种类型来表示两个对象大小之间的差异?

size_t未签名的那样

size_t diff = sizeof (small_struct) - sizeof (big_struct);
Run Code Online (Sandbox Code Playgroud)

显然不正确,在我看来,没有真正的签名等价物.

ptrdiff_t 听起来很诱人,但是

  1. 就像它的名字所说它是用于减去指针.
  2. 我已经读过,例如像DOS这样的分段平台的最大对象大小为64k,可以用16位表示.然而,远指针由16位段值和16位偏移值组成.ptrdiff_t这样的32位平台也不会这样吗?如果是这样,两个对象的大小之间的差异只需要16位,但使用ptrdiff_t会得到一个32位宽的变量,使其不是最佳的.

那么,什么是适合这种价值的便携式?

Edit: 我知道ssize_t,但它是

  1. 不属于标准C.
  2. 实际上并非打算用于此类用途,而是用于返回大小或(负)错误值.

Ben*_*son 18

当我真的担心像这样的溢出问题时(特别是在使用模块化算术时,"负"值包装在其他地方除外~0)我只是把它分成两种情况:

if (a > b) {
    size_t diff = a - b;
} else {
    size_t diff = b - a;
    // code here subtracts diff rather than adds it, etc.
}
Run Code Online (Sandbox Code Playgroud)


Cor*_*lks 8

没有标准的数据类型可以保证100%安全,无法满足您的要求.为了证据,想象一下,如果size_t真的是公正的uint64_t,那是完全可能的.然后没有标准C数据类型保证具有匹配的正范围uint64_t并且还处理负值.

所以对你的问题的直接回答是"没有数据类型"(假设严格遵守标准C,你似乎希望这样).

但是,您不清楚您的用例,并且您可能可以利用模运算来处理"负"值.例如,下面的代码会导致d24因为模运算,允许代码充当如果size_t签署:

#include <stdio.h>
#include <stdint.h>

int main()
{
    size_t d1 = sizeof(int32_t) - sizeof(int64_t);
    size_t d2 = sizeof(int64_t) + d1; // Add difference (even if d1 is "negative"*)

    printf("d1: %zu\n", d1);
    printf("d2: %zu\n", d2);

    return 0;
    // * By "negative" I mean that d1 would be negative if size_t were signed
}
Run Code Online (Sandbox Code Playgroud)

在您的情况下,模块化算术可能不够,但对于其他人可能.