C标准保证int类型能够存储所有可能的数组大小,至少这是我从阅读§6.5.2.1,子节1(数组下标约束)中了解到的。
引用语句如下:
“其中一个表达式应具有“指向对象类型”的指针类型,另一个表达式应具有整数类型,并且结果具有“类型”类型。”
由于我们将使用int作为数组下标,那么为什么我们应该使用size_t来确定数组的大小呢?
为什么strlen()返回size_t,而使用int也可以?
“整数类型”这个术语并不是指 int
- 例如,char
和 short
都是整数类型。
仅仅因为你可以使用一个 int
来对数组进行下标操作,并不意味着它能够到达所有可能的数组元素。
关于 size_t
和 int
的更具体区别,一个例子就是在某些平台上,int
可能是一个16位类型,而 size_t
可能是一个32位类型(或者是今天的64位平台上相较更为普遍的32位 int
vs 64位 size_t
差异)。
INT_MAX
大小的字符串,因为 snprintf
返回 int
并在结果字符串太长时给出溢出错误(即如果您想允许超过 2GB 的字符串,则最佳安全处理字符串的方式变得无法使用)。 - R.. GitHub STOP HELPING ICEint
。同时,在 C 语言中,并不保证 int
可以足够存储任何对象(包括数组)的大小。ptrdiff_t
,而不是 size_t
或者 int
。需要注意的是,ptrdiff_t
是带符号类型,这意味着它的值可以是负数。size_t
的作用是存储程序中任何对象的大小(即存储 sizeof
的结果)。它并不是专门用于数组索引。之所以可以用作数组索引,仅仅是因为它保证足够大以对任何数组进行索引。然而,从抽象的角度来看,"数组" 是一种特定的 "容器",还有其他种类的容器存在(如基于链表或基于树结构的)。在一般情况下,size_t
并不足以存储 任何 容器的大小,因此在一般情况下,将它用作数组索引并不是一个理想的选择。(另一方面,strlen
是一个专门用于处理数组的函数,因此在那里使用 size_t
是适当的。)calloc
,qsort
和fread
/fwrite
都使用一对size_t
值来表示元素大小和元素数量,我不同意您的说法,即size_t
不适用于数组索引。此外,指针算术中的整数操作数可以是任何整数类型,而不仅仅是ptrdiff_t
,但是指针相减的结果具有ptrdiff_t
类型。 - R.. GitHub STOP HELPING ICEsize_t
只能保存您的实现允许创建的最大连续对象的大小。这就是它所能做的全部。没有任何保证您可以创建占用整个内存的对象,因此不能保证 size_t
足以索引整个内存。可用于索引整个内存的整数类型称为 uintptr_t
,而不是 size_t
。size_t
在一般情况下比“整个内存”要小。 - AnT stands with Russiasize_t
,例如DOS / Win16或IBM 128位平台。这些是我的“反例”。但我不关心任何“反例”。反例无关紧要。重要的是size_t
实现了一个非常具体的概念。而这个概念与通用计数无关。这立即使size_t
不适用于通用计数。它是否“足够”都没有任何关系。 - AnT stands with Russiaptrdiff_t
]中无法表示,则行为未定义”。由此可以清楚地看出,ptrdiff_t
不能保证足够大以包含对象中的任何偏移量。而且,ptrdiff_t
不是指针算术中的“整数操作数”。任何整数类型都可以用于指针加法,标准只将ptrdiff_t
作为减法的特例。size_t
是定义为可用于对象中任何正偏移量的类型,而不是ptrdiff_t
。它并不是“碰巧”有效,而是被定义为这样。offsetof
也使用它。 - Steve Jessopsize_t
来执行它设计的功能。在其他语言中,也许可以。 - Steve Jessop在编写C标准时,机器通常具有16位的“int”类型,并且无法处理大于65535字节的任何单个对象,但仍然能够处理大于32767字节的对象。由于无符号int上的算术运算足以处理这些对象的最大大小,但有符号int上的算术运算则不行,因此定义了size_t为无符号,以便容纳这些对象而无需使用“long”计算。
在允许的最大对象大小介于INT_MAX和UINT_MAX之间的机器上,指向该对象开头和结尾的指针之间的差异可能太大而无法适应“int”。虽然标准没有强制要求实现应如何处理它,但常见的方法是定义整数和指针环绕行为,使得如果S和E是char [49152]的开始和结束的指针,则即使E-S超过INT_MAX,它将产生一个值,当添加到S时,将产生E。
现在,size_t是一个无符号类型的事实很少有真正的优势(因为需要大于2GB的对象的代码通常需要出于其他原因使用64位指针),并且它会导致许多涉及对象大小的比较行为反直觉,但sizeof表达式产生无符号类型的事实已经深入人心,不太可能改变。
size_t 是无符号整数的 typedef(如 int 或 long)。
在一些 64 位平台上,int 可能是 32 位,而 size_t 可能是 64 位。
它被用作更标准的尺寸表示方式。
size_t
是某个无符号类型的typedef。隐藏在size_t
背后的类型甚至可能是非标准的,即它可能无法表示为unsigned int
、unsigned long
等。 - AnT stands with Russiasize_t
可能是 unsigned long long
或者甚至是 uintmax_t
。 - Jonathan Leffler
size_t
,这导致了极其严重的可利用漏洞。 - R.. GitHub STOP HELPING ICEmalloc
,它以size_t
作为参数。而且很难知道该使用什么作为数组下标:https://dev59.com/x3A75IYBdhLWcg3wqK7_ - Ciro Santilli OurBigBook.com