为什么我们在 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_t
是 sizeof
运算符返回值的类型这一事实是我们可以假设“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.
我开始学习 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_t
是 sizeof
运算符返回值的类型这一事实是我们可以假设“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.