【问题标题】:What is the difference between ssize_t and ptrdiff_t?ssize_t 和 ptrdiff_t 有什么区别?
【发布时间】:2011-12-27 20:33:35
【问题描述】:

C 标准(ISO/IEC 9899:2011 或 9899:1999)在 <stddef.h> 中定义了一个类型 ptrdiff_t

POSIX 标准(ISO/IEC 9945;IEEE Std 1003.1-2008)在 <sys/types.h> 中定义了一个类型 ssize_t

  • 这些类型之间有什么区别(或者为什么两者都被认为是必要的)?
  • 是否存在ssize_t 的基础基类型与ptrdiff_t 不同的实现?

【问题讨论】:

  • 也许是ptrdiff_t 的语义要求添加ssize_t?有时,带符号的大小类型很有用,如果您希望能够在中间让它代表-1ptrdiff_t 的语义是“两个指针之间的差异”,这并不完全是“大小”的语义。
  • 在相关标准委员会中可能有点 NIH 偏执狂

标签: c posix


【解决方案1】:

是否有一个实现,其中 ssize_t 的基础基类型 和ptrdiff_t不一样?

x86-16 与大内存模型。指针很远(32 位),但单个对象仅限于一个段(因此size_t 允许为 16 位)。

【讨论】:

  • 在那种情况下ptrdiff_t 也不会是 16 位,因为只有当两个指针都指向同一个对象时才定义指针差异...
  • @Dhris: ptrdiff_t 是实现定义的类型,将其设为指针大小似乎是合理的。对于熟悉内存模型的任何人来说,指针上的操作都应该不足为奇,而 16 位 ptrdiff_t 可能会让使用 32 位指针的人感到惊讶。
  • @ChrisDodd:一个对象最多可以有 65535 个字节,因此有效的指针减法很容易超过 32767;对于ptrdiff_t,您需要一个可以容纳高达 65536 值的有符号类型。
  • 这个答案似乎不完整,因为答案没有讨论ssize_t
  • @KeithThompson C 6.5.6-9 允许指针减法(指向同一对象的指针)溢出 ptrdiff_t,可能正是出于这个原因。在更相关的 ILP32/Linux 系统中(所有三种类型都是 32 位),您至少在理论上可以分配超过 2GB 的对象,其中减去指针会溢出 ptrdiff_t 和 ssize_t
【解决方案2】:

开放组基本规范第 7 期,IEEE Std 1003.1,2013 版,<sys/types.h> 的描述说:

类型 ssize_t 能够存储至少在 [-1, SSIZE_MAX] 范围内的值。

换句话说,ssize_t 是有符号的,但是它可以表示的负值集可能仅限于 {-1}。

另一方面,ptrdiff_t 保证具有更对称的正/负范围。

我承认,在实践中,ssize_t 似乎不太可能被限制在负范围内,但这是可能的。

当然,另一个区别是 ptrdiff_t 在您使用标准 C 或 C++ 编程时可用,但 ssize_t 可能不可用,除非您针对标准 POSIX 系统。

【讨论】:

  • 感谢历史信息;即使当前标准不再规定范围,它也有助于解释它的来源。 (我对当前标准的搜索并不是我认为是确定的,尽管我认为它相当彻底;因此“似乎不在 2008 年标准中”的“狡猾措辞”。)
  • 2008 sys/types.h standard[-1, {SSIZE_MAX}] 的要求与 ssize_t 相同。
  • POSIX 说ssize_t 是整数类型,C 标准要求有符号整数类型的最大负值至少与其最大正值一样大。
  • @AdrianMcCarthy 请参阅 C11 6.2.6.2,其中解释了整数中位的允许含义。术语“有符号整数类型”由 6.2.5 定义为包括标准和扩展有符号整数类型。
  • @M.M:啊,关于 6.2.6.2,你说的完全正确。我在 C++ 标准中没有找到类似的东西(“整数类型”的命中率远低于 C 标准)。 6.2.5 语言看起来与 C++ 标准中的语言大致相同,但这并不限制任意整数类型的表示或范围。谢谢!
猜你喜欢
  • 1970-01-01
  • 2010-10-02
  • 2011-12-12
  • 2010-09-16
  • 2012-03-14
  • 2012-02-06
  • 2011-02-25
  • 2011-11-22
  • 2015-03-26
相关资源
最近更新 更多