是size_t
编译代码的机器的字长吗?
使用 g++ 进行解析,我的编译器将size_t
其视为long unsigned int
. 在调用编译器之前,编译器是否在内部选择了 的大小size_t
,或者size_t
实际上是在某个预处理器宏中将其类型定义stddef.h
为字长?
还是我偏离了轨道?
在 C++ 标准中,[support.types] (18.2) /6:“该类型size_t
是实现定义的无符号整数类型,它大到足以包含任何对象的字节大小。”
无论这意味着什么,这可能与“字长”相同,也可能不同。
不; size_t
不一定是您所说的将运行代码(在交叉编译的情况下)或编译代码(在代码将在相同类型的机器上运行的正常情况下)的机器的“字大小”编译代码)。它是一个无符号整数类型,足以容纳实现可以分配的最大对象的大小(以字节为单位)。
sizeof
和size_t
我不知道size_t
确切的介绍是什么时候,但它是在 1979 年到 1989 年之间。1978 年的 K&R The C Programming Language 的第 1 版没有提到size_t
. 第 7 版 Unix Programmer's Manual 根本没有提及size_t
,它的历史可以追溯到 1979 年。Kernighan 和 Pike 于 1984 年出版的“The UNIX Programming Environment”一书size_t
在索引中没有提及(也没有提及malloc()
or free()
,有点令我惊讶) ,但这只是指示性的,不是决定性的。C89 标准当然有size_t
。
C99 基本原理记录了一些关于sizeof()
和的信息size_t
:
6.5.3.4 sizeof 运算符
它是正确使用函数的基础,例如
malloc
和fread
thatsizeof(char)
be one。实际上,这意味着 C 术语中的一个字节是最小的存储单元,即使这个单元是 36 位宽;所有对象都是由这些最小单元的整数个组成。如果内存是位可寻址的,也适用。C89 和 K&R 一样,将sizeof
运算符的结果定义为无符号整数类型的常量。常见的实现和常见的用法通常假设生成的类型是int
. 依赖此行为的旧代码从未移植到将结果定义为非int
. C89 委员会认为更改语言以保护不正确的代码是不合适的。的类型
sizeof
,无论它是什么,都被发布(在库头中<stddef.h>
)为size_t
,因为程序员能够引用这种类型很有用。此要求隐含地限制size_t
为现有无符号整数类型的同义词。另请注意,尽管size_t
是无符号类型,sizeof
但不涉及任何算术运算或转换,如果大小太大而无法表示为 asize_t
,则会导致模数行为,因此消除了任何关于最大可声明对象可能太大而无法跨越的概念即使unsigned long
在 C89 或uintmax_t
C99 中。这也限制了可以在数组中声明的元素的最大数量,因为对于任何 元素数组a
,N
N == sizeof(a)/sizeof(a[0])
因此
size_t
,它也是数组大小的一种方便类型,并且在多个库函数中如此使用。[...]7.17 常用定义
<stddef.h>
是一个头文件,旨在提供与库一起广泛使用的几种类型和宏的定义:ptrdiff_t
、size_t
、wchar_t
和NULL
. 包括引用这些宏之一的任何标头也将定义它,这是通常库规则的一个例外,即每个宏或函数仅属于一个标头。
请注意,这特别提到<stddef.h>
是由 C89 委员会发明的。我没有找到说这size_t
也是由 C89 委员会发明的词,但如果不是,那它是对最近 C 语言发展的编纂。
在对bmargulies answer的评论中,vonbrand说“它 [ size_t
] 肯定是 ANSI-C-ism”。我可以很容易地相信它是原始 ANSI (ISO) C 的一项创新,尽管理由没有说明这一点有点奇怪。
不必要。C ISO 规范(§17.1/2)定义size_t
为
size_t,即
sizeof
运算符结果的无符号整数类型
换句话说,size_t
必须足够大以容纳可以从 生成的任何表达式的大小sizeof
。这可能是机器字长,但它可能会小得多(例如,如果编译器限制了数组或对象的最大大小)或大得多(如果编译器允许您创建如此巨大的对象,以至于单台机器word 无法存储该对象的大小)。
希望这可以帮助!
size_t 原本只是 sys/types.h 中的 typedef(传统上在 Unix/Linux 上)。它被假定为“足够大”,例如文件的最大大小,或 malloc 的最大分配。然而,随着时间的推移,标准委员会抓住了它,因此它最终被复制到许多不同的头文件中,每次都使用自己的#ifdef 保护免受多重定义。另一方面,具有非常大潜在文件大小的 64 位系统的出现掩盖了它的角色。所以它有点像旧书。
语言标准现在将其称为存在于 stddef.h 中。它与硬件字长没有必然关系,也没有编译器魔法。关于这些标准所说的它有多大,请参阅其他答案。
虽然定义没有直接说明具体是什么类型size_t
,甚至没有要求最小尺寸,但它间接给出了一些很好的提示。Asize_t
必须能够包含任何对象的大小(以字节为单位),换句话说,它必须能够包含最大可能对象的大小。
最大的可能对象是一个数组(或结构),其大小等于整个可用地址空间。不可能以有意义的方式引用更大的对象,除了交换空间的可用性之外,没有理由让它需要更小。
因此,按照定义的措辞,在 32 位架构上size_t
必须至少有 32 位,在 64 位系统上必须至少有 64 位。实现当然可以选择更大的size_t
,但通常情况并非如此。
这些定义都是实现定义的。如果我需要一个最佳猜测大小,我会使用 sizeof(char *) 或 sizeof(void *)。这给出的最好的结果是软件使用的明显字长......硬件真正拥有的可能不同(例如,32 位系统可能通过软件支持 64 位整数)。
此外,如果您不熟悉 C 语言,请参阅 stdint.h 以了解有关整数大小的各种材料。