Why size_t when int would suffice for the size of an array?
The C standard guarantees that an int
is able to stor开发者_开发知识库e every possible array size. At least, that's what I understand from reading §6.5.2.1, subsection 1 (Array subscripting constraints):
One of the expressions shall have type ‘‘pointer to object type’’, the other expression shall have integer type, and the result has type ‘‘type’’.
Since we shall use int
s as array subscripts, why are we supposed to use size_t
to determine the size of an array?
Why does strlen()
return size_t
when int
would suffice?
The term "integer type" doesn't mean int
- for example, char
, and short
are integer types.
Just because you can use an int
to subscript an array doesn't necessarily mean that it can reach all possible array elements.
More specifically about size_t
vs. int
, one example would be platforms where int
might be a 16-bit type and size_t
might be a 32-bit type (or the more common 32-bit int
vs 64 bit size_t
difference on today's 64-bit platforms).
integer type is not necessarily an "int". "long long" is an integer type too, as is "size_t".
Arrays can be larger than 2GB. This property is quite handy for those who write memory hungry programs, e.g DBMS with big buffer pools, application servers with big memory caches etc. Arrays bigger than 2GB/4GB is the whole point of 64 bit computing :)
size_t for strlen(), at least sounds compatible with how C standard handles arrays, whether it makes practical sense or not, or whether somebody have seen strings that large, is another question.
Firstly, what you quoted from the standard does not make any references to type int
specifically. And no, int
is not guaranteed to be sufficient to store the size of any object (including arrays) in C.
Secondly, C language does not really have "array subscriptions" specifically. The array subscription is implemented through pointer arithmetic. And the integral operand in pointer arithmetics has ptrdiff_t
type. Not size_t
, not int
, but ptrdiff_t
. It is a signed type, BTW, meaning that the value can be negative.
Thirdly, the purpose of size_t
is to store the size of any object in the program (i.e. to store the result of sizeof
). It is not immediately intended to be used as an array index. It just happens to work as an array index since it is guaranteed that it is always large enough to index any array. However, from an abstract point of view, "array" is a specific kind of "container" and there are other kinds of containers out there (lists-based ones, tree-based ones and so on). In generic case size_t
is not sufficient to store the size of any container, which in generic case makes it a questionable choice for array indexing as well. (strlen
, on the other hand, is a function that works with arrays specifically, which makes size_t
appropriate there.)
When the C Standard was written, it was common for machines to have a 16-bit "int" type, and be incapable of handling any single object larger than 65535 bytes, but nonetheless be capable of handling objects larger than 32767 bytes. Since arithmetic on an unsigned int would be large enough to handle the largest size of such objects, but arithmetic on signed int would not, size_t was defined to be unsigned so as to accommodate such objects without having to use "long" computations.
On machines where the maximum allowable object size is between INT_MAX and UINT_MAX, the difference between pointers to the start and end of such an object may be too large to fit in "int". While the Standard doesn't impose any requirements for how implementations should handle that, a common approach is to define integer and pointer wrap-around behavior such that if S and E are pointers to the start and end of a char[49152], then even though E-S would exceed INT_MAX, it will yield a value which, when added to S, will yield E.
Nowadays, there's seldom any real advantage to the fact that size_t is an unsigned type (since code which needs objects larger than 2GB would often need to use 64-bit pointers for other reasons) and it causes many kinds of comparisons involving object sizes to behave counter-intuitively, but the fact that sizeof expressions yield an unsigned type is sufficiently well entrenched that it's unlikely ever to change.
size_t is a typedef of unsigned integer (such as int or long).
In some 64bit platforms, int can be 32bit, while size_t can be 64bit.
It is used as a more standard way for size.
精彩评论