What is the correct definition of size_t? [duplicate]

和自甴很熟 提交于 2019-12-04 07:41:39

What is "object" in terms of C?

"Object" is a defined term. The C99 standard defines it as: "region of data storage in the execution environment, the contents of which can represent values" (section 3.14). A more colloquial definition might be "the storage in memory for a value." Objects come in different sizes, depending on the type of the value stored. That type includes not only simple types such as char and int, but also complex types such as structures and arrays. For example, the storage for an array is an object, within which is an object for each element.

Why it's limited to 65535, which is maximum number, that could be represented by 16 bits? The article on embedded.com says, that size_t could be 32 bit too.

You misunderstand. Re-read the first two paragraphs of section 7.18.3. SIZE_MAX represents the maximum value of type size_t, but its actual value is implementation dependent. The value given in the standard is the minimum value that that can be. In most implementations it is larger.

K&R says, that int has "natural" size for the platform, and it can be equal to int or to long. So why not use it instead of size_t if it's "natural"?

Because there is no particular reason that the maximum size of an object should be limited to the number of bytes expressible in a single machine word (which is pretty much what the "natural size" means). Nor, where int and long differ in size, is it clear which one should correspond to size_t, if either. Using size_t instead of one of these abstracts away machine details and makes your code more portable.

In response to the update:

I want to know, when to use size_t, when to not use size_t, why it was introduced and what it really represents.

size_t is primarily defined as the type of the result of sizeof. It follows that what it "really represents" is the size of an object.

Use size_t to hold values that represent or are related to the size of an object. That is expressly what it's for. For the most part, you can accomplish this by type matching: use variables of type size_t to store the values declared to have that type, such as the return values of certain functions (e.g. strlen()) and the results of certain operators (e.g. sizeof).

Do not use size_t for values that represent something other than an object size or something closely related (such as the sum or positive difference of object sizes).

when to use size_t

Use size_t to represent non-negative indexes, and to work with values that could be traced back to a sizeof expression.

when to not use size_t

Whenever a value could possibly be negative, e.g. when you subtract pointers. This is allowed for pointers into the same array, but it may yield a negative number, depending on the relative positions of pointers. There is another type ptrdiff_t defined for this situation.

why it was introduced

Designers of the standard had a choice of introducing a separate type, or requiring an existing type to be capable of holding sizes. The first choice gives compiler writers more flexibility, so the designers went with a separate type.

what it really represents

It is capable of representing the size of an object in memory, be it an array, a struct, an array of structs, an array of arrays of structs, or anything else. The size is expressed in bytes.

The type is also convenient for using for non-negative indexes, because it can represent an index to a structure of any size at the maximum granularity (i.e. an index into the largest possible array of chars, because the standard requires char to have the smallest possible size of 1).

Why it's limited to 65535, which is maximum number, that could be represented by 16 bits?

Its atleast 16 bit.

According to the 1999 ISO C standard (C99), size_t is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3).

Why use size_t ?

size_t is a type guaranteed to hold any array index.

size_t can be any of (and also can be anything else other than these) unsigned char, unsigned short, unsigned int, unsigned long or unsigned long long, depending on the implementation.

And to use unsigned int or unsigned long in place of size_t ,reason is similar that they are not the only unsigned integral types.

Its purpose is to relieve the programmer from having to worry about which of the predefined types is used to represent sizes.

On one system, it might make sense to use unsigned int to represent sizes; on another, it might make more sense to use unsigned long or unsigned long long.

So using size_t adds the advantage that code is likely to be more portable.

There is no (single) "correct definition". As said, it's implementation defined.

I want to know, when to use size_t,

For everything related to sizeof() and malloc(). That is, the technical size of objects.

when to not use size_t,

For normal (domain oriented) counting and numbers.

why it was introduced and what it really represents.

It provides an implementation independent way to deal with sizes and allocations, ie it allows you to write portable code.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!