减去2 size_t的类型是什么?

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

由于size_t是无符号的,所以类似于

 size_t diff = sizeof (small_struct) - sizeof (big_struct); 

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

ptrdiff_t听起来有点诱人,但是

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

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

Edit:我知道ssize_t,但它是

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

没有标准数据类型可以保证100%安全,无法满足您的要求。 有关证据,想象一下size_t是否真的只是uint64_t ,这是完全可能的。 然后没有标准的C数据类型保证具有与uint64_t匹配的正范围并且还处理负值。

所以对你的问题的直截了当的答案是“没有数据类型”(假设严格遵守标准C,你似乎希望这样)。

但是,您不清楚您的用例,并且您可能可以利用模运算来处理“负”值。 例如,由于模块化算术, 以下代码导致d24 ,允许代码就像size_t被签名一样:

 #include  #include  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 } 

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

当我真的担心像这样的溢出问题时(特别是在模块化算术中工作时,“负”值包含在除~0以外的某处)我将它分成两种情况:

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

没有签名的C整数类型可以保存size_t值中的所有值。

你可以这样做:

 size_t diff = std::abs(static_cast  (sizeof (small_struct) - sizeof (big_struct)));