ssize_t和ptrdiff_t有什么区别?

Jon*_*ler 41 c posix

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

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

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

dan*_*n04 29

是否存在ssize_t的基础类型与ptrdiff_t不同的实现?

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

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

Adr*_*thy 22

Open Group Base Specifications Issue 7,IEEE Std 1003.1,2013 Edition,描述<sys/types.h>说:

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

换句话说,ssize_t已签名,它可以表示的负值集可能仅限于{-1}.

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

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

当然,另一个区别是,ptrdiff_t无论何时使用标准C或C++编程,ssize_t都可以使用,但除非您的目标是标准POSIX系统,否则可能无法使用.

  • POSIX表示`ssize_t`是整数类型,C标准要求有符号整数类型的最大负值至少与其最大正值一样大. (3认同)
  • @AdrianMcCarthy参见C11 6.2.6.2,它解释了整数内位的允许含义.术语"有符号整数类型"由6.2.5定义为包括标准整数类型和扩展有符号整数类型. (3认同)
  • [2008`sys/types.h` standard](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html)对``[-1,{SSIZE_MAX}]的要求相同` ssize_t`. (2认同)