unsigned int 与 size_t

发布于 2024-07-05 17:57:16 字数 141 浏览 14 评论 0原文

我注意到现代 C 和 C++ 代码似乎几乎到处都使用 size_t 而不是 int/unsigned int - 从 C 字符串函数的参数到STL。 我很好奇这样做的原因以及它带来的好处。

I notice that modern C and C++ code seems to use size_t instead of int/unsigned int pretty much everywhere - from parameters for C string functions to the STL. I am curious as to the reason for this and the benefits it brings.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

自由如风 2024-07-12 17:57:17

类型 size_t 必须足够大才能存储任何可能对象的大小。 Unsigned int 不必满足该条件。

例如,在 64 位系统中,int 和 unsigned int 可能是 32 位宽,但 size_t 必须足够大才能存储大于 4G 的数字

Type size_t must be big enough to store the size of any possible object. Unsigned int doesn't have to satisfy that condition.

For example in 64 bit systems int and unsigned int may be 32 bit wide, but size_t must be big enough to store numbers bigger than 4G

断念 2024-07-12 17:57:17

glibc 手册 0.02 的摘录在研究该主题时也可能相关:

2.4 版之前的 GCC 的 size_t 类型和版本存在潜在问题。 ANSI C 要求 size_t 始终为无符号类型。 为了与现有系统的头文件兼容,GCC 将 stddef.h' 中的 size_t 定义为系统 sys/types.h' 定义的任何类型。 大多数在“sys/types.h”中定义 size_t 的 Unix 系统,将其定义为有符号类型。 库中的某些代码依赖于 size_t 是无符号类型,如果有符号则无法正常工作。

期望 size_t 为无符号的 GNU C 库代码是正确的。 size_t 作为有符号类型的定义不正确。 我们计划在2.4版本中,GCC将始终将size_t定义为无符号类型,并且fixincludes'脚本将修改系统的sys/types.h'以免与此发生冲突。

同时,我们通过在编译 GNU C 库时明确告诉 GCC 对 size_t 使用无符号类型来解决这个问题。 `configure' 将自动检测 GCC 用于 size_t 的类型,并在必要时覆盖它。

This excerpt from the glibc manual 0.02 may also be relevant when researching the topic:

There is a potential problem with the size_t type and versions of GCC prior to release 2.4. ANSI C requires that size_t always be an unsigned type. For compatibility with existing systems' header files, GCC defines size_t in stddef.h' to be whatever type the system'ssys/types.h' defines it to be. Most Unix systems that define size_t in `sys/types.h', define it to be a signed type. Some code in the library depends on size_t being an unsigned type, and will not work correctly if it is signed.

The GNU C library code which expects size_t to be unsigned is correct. The definition of size_t as a signed type is incorrect. We plan that in version 2.4, GCC will always define size_t as an unsigned type, and the fixincludes' script will massage the system'ssys/types.h' so as not to conflict with this.

In the meantime, we work around this problem by telling GCC explicitly to use an unsigned type for size_t when compiling the GNU C library. `configure' will automatically detect what type GCC uses for size_t arrange to override it if necessary.

何以畏孤独 2024-07-12 17:57:17

如果我的编译器设置为 32 位,则 size_t 只不过是 unsigned int 的 typedef。 如果我的编译器设置为 64 位,则 size_t 只不过是 unsigned long long 的 typedef。

If my compiler is set to 32 bit, size_t is nothing other than a typedef for unsigned int. If my compiler is set to 64 bit, size_t is nothing other than a typedef for unsigned long long.

戏舞 2024-07-12 17:57:17

size_t 是指针的大小。

所以在32位或者常见的ILP32(整数、长整型、指针)模型中size_t是32位。
而在64位或常见的LP64(长整型,指针)模型中,size_t是64位(整数仍然是32位)。

还有其他模型,但这些是 g++ 使用的模型(至少默认情况下)

size_t is the size of a pointer.

So in 32 bits or the common ILP32 (integer, long, pointer) model size_t is 32 bits.
and in 64 bits or the common LP64 (long, pointer) model size_t is 64 bits (integers are still 32 bits).

There are other models but these are the ones that g++ use (at least by default)

ぺ禁宫浮华殁 2024-07-12 17:57:16

size_t 类型是无符号整数类型,是 sizeof 运算符(和 offsetof 运算符)的结果,因此保证是足够大以包含系统可以处理的最大对象的大小(例如,8Gb 的静态数组)。

size_t 类型可能大于、等于或小于 unsigned int,并且您的编译器可能会对其进行假设以进行优化。

您可以在 C99 标准第 7.17 节中找到更准确的信息,该草案可在 Internet 上的 pdf 格式,或 C11 标准第 7.19 节,也可作为 pdf 草案

The size_t type is the unsigned integer type that is the result of the sizeof operator (and the offsetof operator), so it is guaranteed to be big enough to contain the size of the biggest object your system can handle (e.g., a static array of 8Gb).

The size_t type may be bigger than, equal to, or smaller than an unsigned int, and your compiler might make assumptions about it for optimization.

You may find more precise information in the C99 standard, section 7.17, a draft of which is available on the Internet in pdf format, or in the C11 standard, section 7.19, also available as a pdf draft.

残月升风 2024-07-12 17:57:16

经典 C(Brian Kernighan 和 Dennis Ritchie 在《C 编程语言》,Prentice-Hall,1978 年描述的 C 的早期方言)不提供 size_t。 C 标准委员会引入了 size_t 来消除可移植性问题

embedded.com 上有详细解释(有一个很好的例子)

Classic C (the early dialect of C described by Brian Kernighan and Dennis Ritchie in The C Programming Language, Prentice-Hall, 1978) didn't provide size_t. The C standards committee introduced size_t to eliminate a portability problem

Explained in detail at embedded.com (with a very good example)

烟酉 2024-07-12 17:57:16

简而言之,size_t 永远不会是负数,并且它可以最大限度地提高性能,因为它被类型定义为无符号整数类型,该类型足够大(但不是太大)来表示最大可能对象的大小在目标平台上。

大小永远不应该为负数,实际上 size_t 是一个无符号类型。 另外,由于 size_t 是无符号的,因此您可以存储大约是相应有符号类型中两倍大的数字,因为我们可以使用符号位来表示大小,就像无符号中的所有其他位一样整数。 当我们多获得一位时,我们可以将我们可以表示的数字范围乘以大约两倍。

那么,您可能会问,为什么不直接使用 unsigned int 呢? 它可能无法容纳足够多的数字。 在 unsigned int 为 32 位的实现中,它可以表示的最大数字是 4294967295。 某些处理器(例如 IP16L32)可以复制大于 4294967295 字节的对象。

那么,您可能会问,为什么不使用 unsigned long int 呢? 它会在某些平台上造成性能损失。 标准 C 要求 long 至少占用 32 位。 IP16L32 平台将每个 32 位长实现为一对 16 位字。 这些平台上的几乎所有 32 位运算符都需要两条指令(甚至更多),因为它们在两个 16 位块中处理 32 位。 例如,移动 32 位长通常需要两条机器指令——一条指令用于移动每个 16 位块。

使用 size_t 可以避免这种性能损失。 根据这篇精彩的文章,“类型 size_t 是一个 typedef,它是某些无符号整数类型的别名,通常是 unsigned intunsigned long,但甚至可能是 unsigned long每个标准 C 实现都应该选择足够大的无符号整数(但不会大于所需的大小)来表示目标平台上最大可能对象的大小。

In short, size_t is never negative, and it maximizes performance because it's typedef'd to be the unsigned integer type that's big enough -- but not too big -- to represent the size of the largest possible object on the target platform.

Sizes should never be negative, and indeed size_t is an unsigned type. Also, because size_t is unsigned, you can store numbers that are roughly twice as big as in the corresponding signed type, because we can use the sign bit to represent magnitude, like all the other bits in the unsigned integer. When we gain one more bit, we are multiplying the range of numbers we can represents by a factor of about two.

So, you ask, why not just use an unsigned int? It may not be able to hold big enough numbers. In an implementation where unsigned int is 32 bits, the biggest number it can represent is 4294967295. Some processors, such as the IP16L32, can copy objects larger than 4294967295 bytes.

So, you ask, why not use an unsigned long int? It exacts a performance toll on some platforms. Standard C requires that a long occupy at least 32 bits. An IP16L32 platform implements each 32-bit long as a pair of 16-bit words. Almost all 32-bit operators on these platforms require two instructions, if not more, because they work with the 32 bits in two 16-bit chunks. For example, moving a 32-bit long usually requires two machine instructions -- one to move each 16-bit chunk.

Using size_t avoids this performance toll. According to this fantastic article, "Type size_t is a typedef that's an alias for some unsigned integer type, typically unsigned int or unsigned long, but possibly even unsigned long long. Each Standard C implementation is supposed to choose the unsigned integer that's big enough--but no bigger than needed--to represent the size of the largest possible object on the target platform."

夏の忆 2024-07-12 17:57:16

size_t 类型是 sizeof 运算符返回的类型。 它是一个无符号整数,能够表示主机支持的任何内存范围的字节大小。 它(通常)与 ptrdiff_t 相关,因为 ptrdiff_t 是有符号整数值,因此 sizeof(ptrdiff_t) 和 sizeof(size_t) 相等。

编写 C 代码时,无论何时处理内存范围,您都应该始终使用 size_t。

另一方面,int 类型基本上定义为主机可以用来最有效地执行整数算术的(有符号)整数值的大小。 例如,在许多较旧的 PC 类型计算机上,值 sizeof(size_t) 将为 4(字节),但 sizeof(int) 将为 2(字节)。 尽管 CPU 可以处理高达 4 GiB 的(逻辑)内存空间,但 16 位算术比 32 位算术更快。

仅当您关心效率时才使用 int 类型,因为它的实际精度在很大程度上取决于编译器选项和机器体系结构。 特别是,C 标准指定了以下不变量: sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) 对程序员可用的精度的实际表示没有其他限制对于这些原始类型中的每一个。

注意:这与 Java 中的不同(Java 实际上指定了“char”、“byte”、“short”、“int”和“long”每种类型的位精度)。

The size_t type is the type returned by the sizeof operator. It is an unsigned integer capable of expressing the size in bytes of any memory range supported on the host machine. It is (typically) related to ptrdiff_t in that ptrdiff_t is a signed integer value such that sizeof(ptrdiff_t) and sizeof(size_t) are equal.

When writing C code you should always use size_t whenever dealing with memory ranges.

The int type on the other hand is basically defined as the size of the (signed) integer value that the host machine can use to most efficiently perform integer arithmetic. For example, on many older PC type computers the value sizeof(size_t) would be 4 (bytes) but sizeof(int) would be 2 (byte). 16 bit arithmetic was faster than 32 bit arithmetic, though the CPU could handle a (logical) memory space of up to 4 GiB.

Use the int type only when you care about efficiency as its actual precision depends strongly on both compiler options and machine architecture. In particular the C standard specifies the following invariants: sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) placing no other limitations on the actual representation of the precision available to the programmer for each of these primitive types.

Note: This is NOT the same as in Java (which actually specifies the bit precision for each of the types 'char', 'byte', 'short', 'int' and 'long').

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文