【发布时间】:2010-10-04 21:49:33
【问题描述】:
在几个 C++ 示例中,我看到了 size_t 类型的使用,而我会使用简单的 int。有什么区别,为什么size_t 应该更好?
【问题讨论】:
-
有关它们不可互换的实际示例,请参阅我之前提出的问题:stackoverflow.com/questions/645168/…
在几个 C++ 示例中,我看到了 size_t 类型的使用,而我会使用简单的 int。有什么区别,为什么size_t 应该更好?
【问题讨论】:
size_t 类型定义为sizeof 运算符的无符号整数类型。在现实世界中,您经常会看到 int 定义为 32 位(为了向后兼容),但 size_t 在 64 位平台上定义为 64 位(因此您可以声明大小超过 4 GiB 的数组和结构)。如果 long int 也是 64 位的,这称为 LP64 约定;如果 long int 是 32 位但 long long int 和指针是 64 位,那就是 LLP64。您也可能得到相反的结果,该程序使用 64 位指令来提高速度,但使用 32 位指针来节省内存。此外,int 已签名,size_t 未签名。
从历史上看,有许多其他平台的地址比int 的原始大小更宽或更短。事实上,在 70 年代和 80 年代初期,这种情况比较普遍:所有流行的 8 位微机都有 8 位寄存器和 16 位地址,而 16 位和 32 位之间的转换也产生了许多机器地址比他们的寄存器更宽。我偶尔还会在这里看到有关用于 MS-DOS 的 Borland Turbo C 的问题,它的巨大内存模式在 16 位 CPU 上以 32 位存储 20 位地址(但它可以支持 80386 的 32 位指令集);摩托罗拉 68000 有一个 16 位 ALU,带有 32 位寄存器和地址;有 15 位、24 位或 31 位地址的 IBM 大型机。您还可以在嵌入式系统中看到不同的 ALU 和地址总线大小。
任何时候int 小于size_t,并且您尝试将非常大的文件或对象的大小或偏移量存储在unsigned int 中,它可能会溢出并导致错误。使用int,也有可能得到一个负数。如果int 或unsigned int 更宽,程序将正常运行但会浪费内存。
如果您想要可移植性,您通常应该使用正确的类型。很多人会建议您使用有符号数学而不是无符号数学(以避免像1U < -3 这样的讨厌的、微妙的错误)。为此,标准库将<stddef.h> 中的ptrdiff_t 定义为从另一个指针中减去一个指针的结果的有符号类型。
也就是说,一种解决方法可能是根据INT_MAX 和0 或INT_MIN 对所有地址和偏移量进行边界检查,并在您错过时打开有关比较有符号和无符号数量的编译器警告任何。无论如何,您应该始终、始终、始终检查您的数组访问是否存在溢出。
【讨论】:
SIZE_T 的定义位于:
https://msdn.microsoft.com/en-us/library/cc441980.aspx 和 https://msdn.microsoft.com/en-us/library/cc230394.aspx
在此处粘贴所需信息:
SIZE_T 是一个ULONG_PTR,表示指针可以指向的最大字节数。
该类型声明如下:
typedef ULONG_PTR SIZE_T;
ULONG_PTR 是用于指针精度的无符号长类型。它用于将指针转换为 long 类型以执行指针运算。
该类型声明如下:
typedef unsigned __int3264 ULONG_PTR;
【讨论】:
SIZE_T 不是 size_t,OP 询问的内容。
SIZE_T 与size_t 完全不同。您不能声明SIZE_T 类型的变量。
stdlib.h 和 stddef.h 头文件定义了一个名为 size_t 的数据类型,用于表示对象的大小。采用 size 的库函数期望它们是 size_t 类型,并且 sizeof 运算符的计算结果为 size_t。
size_t 的实际类型取决于平台;一个常见的错误是假设 size_t 与 unsigned int 相同,这可能导致编程错误,尤其是在 64 位架构变得越来越普遍的情况下。
另外,请检查Why size_t matters
【讨论】:
/usr/include/stdlib.h 从 /usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.h 获取定义,其中默认为 long unsigned int,除非其他头文件另有说明。
size_t 是用于表示尺寸的类型(顾名思义)。它依赖于平台(甚至可能是实现),并且应该仅用于此目的。显然,表示一个大小,size_t 是无符号的。许多 stdlib 函数,包括 malloc、sizeof 和各种字符串操作函数都使用 size_t 作为数据类型。
默认情况下,int 已签名,尽管它的大小也取决于平台,但在大多数现代机器上它将是固定的 32 位(虽然 size_t 在 64 位架构上是 64 位,但 int 在那些架构上保持 32 位长) )。
总结一下:使用 size_t 表示对象的大小,在其他情况下使用 int(或 long)。
【讨论】:
这是因为 size_t 可以是除 int 以外的任何东西(可能是结构)。这个想法是将其工作与底层类型分离。
【讨论】:
size_t 被指定为 无符号整数 类型。 C11 §6.5.3.4 5“两个运算符的结果值(sizeof_Alignof)是实现定义的,其类型(无符号整数类型)是size_t,”。