为什么我们在 C 中指定 size_t 数组大小而不是仅使用整数?这样做的好处是什么?

Why do we specify size_t array size in C rather than just using integers? And what are the advantages to do so?

我开始学习 C,我的一个家庭作业要求我创建一个数组 size_t const N_MAX = 10; double v1[N_MAX]; 我知道 size_t 代表 v1 数组长度,但我仍然不明白 size_t 类型在这里有什么贡献,而不是使用 int N_MAX?

size_t can store the maximum size of a theoretically possible object of any type (including array).

size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.

(source)

这意味着 size_t 保证能够在您编译的任何平台上保持任何 size/index 计数。

它通常是根据您编译的目标平台来定义的。例如Windows SDK中包含的intsafe.h header定义如下:

#ifdef _WIN64
typedef __int64             ptrdiff_t;
typedef unsigned __int64    size_t;
#else
typedef int            ptrdiff_t;
typedef unsigned int   size_t;
#endif

直接使用 size_t 意味着您不必担心在为不同的体系结构(例如 x86)重新编译时更改用于索引或保持 object 大小的数据类型与 x86-64 相比)。

编辑:正如@Eric Postpischil 在评论中提到的那样,C 标准的实际措辞与我从 cppreference 链接的解释不同。

查看 the standard 我们可以看到关于 size_t 的一些提及:

6.5.3.4 The sizeof and alignof operators

[...]

5 The value of the result of both operators is implementation-defined, and its type (an unsigned integer type) is size_t, defined in <stddef.h> (and other headers)

[...]

7.19 Common definitions <stddef.h>

[...]

size_t which is the unsigned integer type of the result of the sizeof operator;

size_tsizeof 运算符返回值的类型这一事实是我们可以假设“size_t 可以存储最大大小的原因理论上可能 object 任何类型”,但实际上在标准中没有任何地方强制要求。该标准还说明了以下关于 sizeof 的内容:

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant

我的解释(这可能是错误的)是你不能有一个 object 尺寸不适合 size_t因为在那种情况下你不能有一个有效的 sizeof 操作员。

编辑 2:

我将在这里引用 Eric Postpischil:

There are simply limits as to what we can do with computers, and sometimes calculations go out of bounds. It is generally easy on modern hardware to define size_t so that sizeof always works, and you obviously cannot malloc a larger object, but you might construct one with a static array, in some esoteric C implementation with 16-bit size_t but 22-bit addresses.