【发布时间】:2012-12-21 13:17:17
【问题描述】:
C 中应该使用哪种类型来表示两个对象大小之间的差异?
由于size_t 是未签名的,类似于
size_t diff = sizeof (small_struct) - sizeof (big_struct);
显然不正确,在我看来,没有真正的签名等价物。
ptrdiff_t 听起来有点诱人,但是
- 正如它的名字所说,它是用于减去指针。
- 我读过,例如像 DOS 这样的分段平台具有 64k 的最大对象大小,可以用 16 位表示。然而,远指针由一个 16 位段值和一个 16 位偏移值组成。这不会使
ptrdiff_t在这样的平台上也成为 32 位吗? 如果是这样,两个对象之间的大小差异只需要 16 位,但使用 ptrdiff_t 会给您一个 32 位宽的变量,使其不是最佳的。
那么,使用这种值的合适的可移植类型是什么?
Edit:
我知道 ssize_t,但它是
- 不是标准 C 的一部分。
- 实际上并非用于此类用途,而是用于返回大小或(负)错误值。
【问题讨论】:
-
@AFAIK
ssize_t是 POSIX,而不是 ISO C。 -
@RomanR。
ssize_t不是 C 标准,size_t的值不能保证适合 POSIX 中的ssize_t。 -
这个问题的问题在于它没有解释它应该是什么意思。您可以设想在某种程度上增加结构尺寸,例如用于计算布局,尽管由于结构对齐规则,这已经很麻烦了。结构尺寸的差异真正代表什么?这段代码出现在什么上下文中?如果你不能解释,那么你也不能为它编写正确的代码。
-
@Mehrdad: C11, 6.5.7/9: "当两个指针相减时,[...] 结果的大小是实现定义的,其类型(有符号整数类型)是在
头文件中定义的 ptrdiff_t。如果结果在该类型的对象中不可表示,则行为未定义。” 因此,不能保证(尽管这指的是指针地址,因为这是ptrdiff_t的用途,而不是对象大小)。 -
@netcoder:没错,但这不是全部。你不能减去任意指针;它们必须指向同一个对象。因此,如果
ptrdiff_t可以保持它们的差异(假设一个指针指向对象的开头,另一个指向对象的结尾),并且size_t可以保持对象的大小,根据定义在两者不能丢失信息。不过,它是否溢出符号位当然是一个不同的问题——但这些位是存在的。