Think,Make

原文Why size_t matters

合理的使用size_t可以提高程序的可移植性和代码的可读性,让你的程序更高效。

Numerous functions in the Standard C library accept arguments or return values that represent object sizes in bytes. For example, the lone argument in malloc(n) specifies the size of the object to be allocated, and the last argument in memcpy(s1, s2, n) specifies the size of the object to be copied. The return value of strlen(s) yields the length of (the number of characters in) null-terminated character array s excluding the null character, which isn’t exactly the size of s, but it’s in the ballpark.

在标准C库中,许多函数接收参数,或者返回对象的字节大小。例如,malloc(n)函数中,唯一的实参n指定要分配对象的大小;memcpy(s1, s2, n)函数中,最后一个实参n指定要拷贝对象的大小。还有strlen(s)函数的返回值得到的是数组s中以NULL结尾的非空字符的个数(不包括NULL在内),当然这不是s的真正长度,但这是可以接受的。

You might reasonably expect these parameters and return types that represent sizes to be declared with type int (possibly long and/or unsigned), but they aren’t. Rather, the C standard declares them as type size_t. According to the standard, the declaration for malloc should appear in <stdlib.h> as something equivalent to:

你可能想当然地认为,这些表示大小的形参和返回值的类型会被声明为int类型(也可能是long类型及他们对应的unsigned类型),但事实上并不是这样。相反,标准C声明他们为size_t类型。根据标准,malloc()函数应该在stdio.h中有类似的声明:

void *malloc(size_t n);

and the declarations for memcpy and strlen should appear in <string.h> looking much like:

同时,memcpy()函数和strlen()函数在string.h中也要有类似的声明:

void *memcpy(void *s1, void const *s2, size_t n);size_t strlen(char const *s);

The type size_t also appears throughout the C++ standard library. In addition, the C++ library uses a related symbol size_type, possibly even more than it uses size_t.

size_t类型也遍及C++标准库。另外,C++标准库使用一个相关的符号size_type,可能更倾向于使用这个。

In my experience, most C and C++ programmers are aware that the standard libraries use size_t, but they really don’t know what size_t represents or why the libraries use size_t as they do. Moreover, they don’t know if and when they should use size_t themselves.

以我的经验,大多数C和C++程序员虽然知道标准库使用size_t,但他们真的不清楚size_t表示什么或者为什么标准库使用size_t。此外,他们也不知道何时使用、是否使用size_t。

In this column, I’ll explain what size_t is, why it exists, and how you should use it in your code.

在本专栏中,我将解释size_t是什么,他为什么会存在,以及在你的代码中如何使用他。

可移植性问题

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, illustrated by the following example.

传统的C(早期在The C Programming Language, Prentice-Hall, 1978一书中,Brian Kernighan和Dennis Ritchie对C的描述)并没有提供size_t。后来C标准委员会提出size_t来解决可移植性问题,如以下这个例子。

Let’s examine the problem of writing a portable declaration for the standard memcpy function. We’ll look at a few different declarations and see how well they work when compiled for different architectures with different-sized address spaces and data paths.

让我们来为标准memcpy()函数写一个具有可移植性的声明,并检查他所存在的问题。我们一起来看几种不同的声明,看看他们在具有不同大小的地址空间和数据路径的体系结构下编译之后,是如何工作的。

Recall that calling memcpy(s1, s2, n) copies the first n bytes from the object pointed to by s2 to the object pointed to by s1, and returns s1. The function can copy objects of any type, so the pointer parameters and return type should be declared as "pointer to void." Moreover, memcpy doesn’t modify the source object, so the second parameter should really be "pointer to const void." None of this poses a problem.

调用memcpy()函数,会把s2指向的对象的前n个字节拷贝到s1所指向的对象中,并返回s1。这个函数可以拷贝任意类型的对象,所以指针形参和返回类型应该声明为“指向void的指针”。同时,memcpy()不能修改源对象,所以第二个形参应该为“指向const void的指针”。这些都不会引起问题。

The real concern is how to declare the function’s third parameter, which represents the size of the source object. I suspect many programmers would choose plain int, as in:

真正应该关心的是如何声明函数的第三个形参,也就是代表了源对象大小的的那个形参。我猜很多程序员会选择再简单不过的int类型,就像这样:

void *memcpy(void *s1, void const *s2, int n);

which works fine most of the time, but it’s not as general as it could be. Plain int is signed–it can represent negative values. However, sizes are never negative. Using unsigned int instead of int as the type of the third parameter lets memcpy copy larger objects, at no additional cost.

人生不如意十之八-九,与其诅咒黑暗,倒不如在生命中点燃一盏灯

Think,Make

相关文章:

你感兴趣的文章:

标签云: