size_t的正确定义是什么?

Gil*_*tes 5 c c99 size-t c11

首先,我的意思是'正确定义'?

例如,"C编程语言"第2版中的 K&R .,在2.2数据类型和大小中,对整数做出非常明确的陈述:

  • 还有short,intlong用于整数类型.他们需要重复不同边界的价值观.
  • int 是特定硬件的"自然"大小的数字,因此也可能是最快的.
  • 尺寸为整数类型short,intlong纯粹是实现相关的.
  • 但他们有限制.
  • short并且int应至少保留16位.
  • long 应至少保留32位.
  • short> = int> = long.

这是非常明确和明确的.size_t类型不是这种情况.在K&R 5.4地址算术中,他们说:

  • ... size_tsizeof运算符返回的无符号整数类型.
  • sizeof操作者产生存储其操作数的类型的对象所需要的字节数.

C99标准草案中,在6.5.3.4尺寸操作员中,他们说:

  • 结果的值是实现定义的,其类型(无符号整数类型)size_t<stddef.h>(和其他头文件)中定义.

7.17通用定义中:

  • size_t 这是sizeof运算符的结果的无符号整数类型;

7.18.3其他整数类型的限制中:

  • size_t SIZE_MAX65535的限制

还有一篇有用的文章 - 为什么size_t很重要.它说如下:

  • 好吧,让我们试着想象一下,如果没有,会是什么样的size_t.
  • 例如,让我们从中获取void *memcpy(void *s1, void const *s2, size_t n);标准函数<string.h>
  • 让我们用int,而不是size_t用于n参数.
  • 但是内存的大小不能是负面的,所以让我们更好unsigned int.
  • 好,好像我们现在和没有幸福size_t.
  • 但是unsigned int有限的尺寸 - 如果有一台机器,可以复制大于unsigned int可以容纳的内存块?
  • unsigned long那么,让我们使用,现在我们很高兴?
  • 但是对于那些使用较小内存块运行的机器unsigned long来说效率低下,因为long它们不是"自然"的,它们必须执行额外的操作才能使用 longs.
  • 因此,我们需要size_t- 代表内存大小,特定硬件可以同时运行.在某些机器上这将是等于int,在其他人- long,这取决于哪种类型,他们是最有效的.

我从中理解的是,它size_tsizeof运营商严格限制.因此size_t表示对象的最大大小(以字节为单位).它也可能表示特定CPU模型可以同时移动的多个字节.

但这里仍有许多神秘之处:

  • 什么是C语言中的"对象"?
  • 为什么它被限制为65535,这是最大数量,可以用16位表示?embedded.com上的文章说,也size_t可能是32位.
  • K&R表示,int平台具有"自然"尺寸,可以等于int或等于long.那么为什么不使用它而不是size_t它是"自然的"?

UPDATE

有类似的问题:

什么是C中的size_t?

但它的答案并未提供明确的定义或与权威来源的链接(如果不算维基百科那样).

我想知道何时使用size_t,什么时候不使用size_t,为什么它被引入,以及它真正代表什么.

Joh*_*ger 3

C语言中的“对象”是什么?

“对象”是一个定义好的术语。C99标准将其定义为:“执行环境中数据存储的区域,其内容可以表示值”(第3.14节)。更通俗的定义可能是“内存中值的存储”。对象有不同的大小,具体取决于存储值的类型。该类型不仅包括char和 等简单类型int,还包括结构体和数组等复杂类型。例如,数组的存储是一个对象,其中每个元素都有一个对象。

为什么它被限制为 65535,这是 16 位可以表示的最大数字?Embedded.com 上的文章说,size_t 也可以是 32 位。

你误会了。重新阅读第 7.18.3 节的前两段。SIZE_MAX表示 type 的最大值size_t,但其实际值取决于实现。标准中给出的值是可以达到的最小值在大多数实现中它更大。

K&R 表示,int 对于平台来说具有“自然”大小,它可以等于 int 或 long。那么,如果它是“自然的”,为什么不使用它来代替 size_t 呢?

因为没有特殊原因表明对象的最大大小应限制为单个机器字可表达的字节数(这几乎就是“自然大小”的含义)。也不清楚int和 的long大小在哪里不同,如果有的话,哪一个应该对应于size_t。使用size_t而不是其中之一会抽象出机器细节,并使您的代码更加可移植。

响应更新:

我想知道,何时使用 size_t,何时不使用 size_t,为什么引入它以及它真正代表什么。

size_t主要定义为 的结果的类型sizeof。由此可见,它“真正代表”的是物体的大小。

用于size_t保存表示对象大小或与对象大小相关的值。这显然是它的用途。大多数情况下,您可以通过类型匹配来完成此操作:使用类型变量size_t来存储声明为该类型的值,例如某些函数的返回值(例如strlen())和某些运算符的结果(例如sizeof)。

不要用于size_t表示对象大小以外的值或密切相关的值(例如对象大小的总和或正差)。

  • @GillBates,是的。这就是“依赖于实现”的含义。该标准给出了符合标准的编译器必须提供的最低限度,但编译器/库开发人员可以选择。通常,该选择由目标运行时环境的特征决定,但并非必须如此。 (2认同)