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