GCC 4.4.1,C99
我正在使用 size_t
,而 size_t
是一个 unsigned int
。 然而,这取决于您是否运行在32位或64位上。
我将使用 size_t
来存储缓冲区的大小。
所以,如果在不同的体系结构之间使用,我认为这可能不太可移植。
只是一个问题,使用 size_t
在32位或64位上会引起什么情况下的严重问题?
GCC 4.4.1,C99
我正在使用 size_t
,而 size_t
是一个 unsigned int
。 然而,这取决于您是否运行在32位或64位上。
我将使用 size_t
来存储缓冲区的大小。
所以,如果在不同的体系结构之间使用,我认为这可能不太可移植。
只是一个问题,使用 size_t
在32位或64位上会引起什么情况下的严重问题?
size_t
是正确的并且非常适合用于存储 sizeof()
的结果或任何可表示对象的大小(以字节为单位)。但是,您需要注意以下几点:
size_t
与某些无符号整数类型的大小相同。它的字节数不一定与最大的无符号整数类型(例如 unsigned int
,unsigned long
等)相同。sizeof(size_t)
是一个实现定义的字节数,因此将其复制到任何整数类型中(除了 uintmax_t
)或对其进行赋值是不明智的。我甚至不确定假设它与 uintmax_t
相等或更小是否安全。size_t
值写入二进制文件,然后通过另一个进程、在不同机器上或使用不同编译器选项编译的程序读回到 size_t
中可能会有危险。size_t
值,并尝试在另一端使用 sizeof(size_t)
缓冲区接收它是相当不安全的。unsigned char
之外。因此,size_t
和任何其他整数类型一样具有可移植性。size_t
保证能够保存你的实现中任何对象的字节数。这就是为什么sizeof
的返回类型是size_t
。
因此,它是可移植的。
如果你正在使用malloc()或read(),那么使用size_t或ssize_t来表示缓冲区大小是有意义的。为了提高可移植性,可以使用SIZE_MAX、SSIZE_MAX、sizeof(type-in-your-buffer)和%zd或%zu printf()。
printf()
函数中的 z
大小修饰符。 - Phil Millerz
修饰符是C99标准的一部分。迄今为止,Microsoft编译器使用的是C89/90。在C89/90中,必须手动实现size_t
打印的“可移植性”。 - AnT stands with Russiaz
长度修饰符,还支持其他一些长度修饰符。请参阅C Runtime (CRT) Features, Fixes, and Breaking Changes in Visual Studio 14 CTP1中的<stdio.h>
和<conio.h>
主题。 - MikeOnline你还有off_t和ptrdiff_t/ssize_t,它们在不同架构之间也会有所不同。
如果你正确使用它们,它们就可以跨架构移植。在32位系统上,它们都将是32位宽度,而在64位系统上,它们都将是64位宽度。这正是你想要的 - 在32位系统上,缓冲区的大小不可能比32位size_t更大,但在64位系统上,它可以远远超过32位。
你永远不应该使用int、long或其他任何类型。除此之外,long的大小取决于平台(在大多数32位系统上为32位,在64位Unix系统上为64位,在64位Windows上为32位)。
这取决于您使用 size_t 的用途。
如果您将其用于确定内存缓冲区的大小,那么它是安全的,因为 size_t 足够大以寻址任何计算机的整个内存。因此,如果内存缓冲区大于该值,则无论如何都会出现问题。
另一方面,如果您将其用作通用的无符号整数来计算宇宙中星星的数量,例如,在 32 位系统上可能会出现问题(不确定 64 位系统是否有问题)。
size_t
足以容纳实现支持的最大对象的大小。 size_t
不足以寻址整个内存。对于后者,您需要使用intptr_t
/ uintptr_t
。 - AnT stands with Russia唯一真正的严重问题是尝试访问相当大的数组或size_t的大数字。
就像普通的“int”在64位上可能足够,但在32位系统上因为它对于32位系统上的int来说太大而导致崩溃。