g_b
g_b

Reputation: 12438

"Largest possible object" on size_t explanations

I know there is a similar question here but it's not clear to me. I've just begun learning C++ and stumbled upon size_t. I've read about it and I think I understand its purpose, but on most explanations, they use the phrase "Largest possible object" your system can handle.

What do they mean when they say object? The objects I know are the ones instantiated from classes, but I can add a lot of properties on that object so I don't think this is the type of object that they are referring to.

Upvotes: 4

Views: 7259

Answers (3)

AnT stands with Russia
AnT stands with Russia

Reputation: 320631

The standard meaning of the term object is not tied to classes specifically. The term originates from C language and its meaning hasn't changed much in C++. The term "object" is a loose synonym of the term "variable", any variable. Every variable you declare is an object. All of the following are objects

int a;                // an object of type 'int'
double b;             // an object of type 'double'
char s[1024];         // an object of type 'char [1024]'
SomeClass x;          // an object of type 'SomeClass'
SomeOtherClass y[10]; // an object of type 'SomeOtherClass [10]'

In other words, objects are pieces of data stored in memory, as opposed to functions, which are made of code.

The specification of type size_t says that it should be able to store the size of the largest object supported by the implementation. Typically, the easiest way to create a large object is to declare an array of large size. Of course, you can also create a large object by creating a sufficiently large class type.

Maximum object size supported by an implementation is typically an inherent property of that implementation (which possibly depends on compiler settings too). It is hardcoded into the implementation. So, if size_t is large enough to cover that range, it will always be enough to store the size of any object.

For example, some implementation might limit the maximum object size by 64K bytes. In such implementation size_t can be safely defined as a 16-bit unsigned integer. This size_t will always be large enough to store the size of any object (the result of any sizeof), since the implementation will never allow you to create a larger object or declare a type of larger size.


There's another standard type somewhat tied to the largest possible object size - ptrdiff_t. This is a signed type that is intended to store the difference between two pointers pointing into the same array. If some implementation would allow you to create objects (e.g. a char array) as large as the maximum value of size_t, then in order to accommodate any difference between such pointers, ptrdiff_t would have to be at least 1 bit wider than size_t (due to its signedness). I.e. if size_t was 16 bit wide, ptrdiff_t would have to be at least 17 bit wide. This is a rather odd situation.

However, fortunately (or unfortunately) implementations are not required to be able to store any difference between two pointers in ptrdiff_t. Which means that they have an excuse to define ptrdiff_t of the same width as size_t.

Some implementations take advantage of that excuse: they define size_t and ptrdiff_t of the same width. They allow you to create objects as large as the max value of size_t. And also tell you to be careful when subtracting distant pointers: the result might not fit into ptrdiff_t, overflow and cause undefined behavior.

Other implementations follow a different approach: they also define size_t and ptrdiff_t of the same width, but they artificially limit the max object size by half the range of size_t. In such implementations any two pointers that point into the same array can always be safely subtracted. (But obviously you pay for that with max object size reduced by the factor of 2).

Upvotes: 10

Malcolm McLean
Malcolm McLean

Reputation: 6404

The code

 char array[100000];

must have a size which fits in a size_t. The compiler will usually reject for other reasons as arrays approach SIZE_MAX, but SIZE_MAX is a solid limit.

You'll also note that sizeof(int) returns a size_t. However this number is probably 2 or 4 and most unlikely to be greater than 8. So whilst size_t is designed to allow large numbers to be handled, most uses are for small numbers.

You'll also note that the code

     int *array = malloc(N * sizeof(int));
     for(i=0;i<N;i++)
        array[i] = 0;

should really have size_t's for N and i. This is where the size_t idea starts being a nuisance. Unsigned values for array indices make the indices hard to manipulate.

And "object" in C is anything that can be identified, and occupies contiguous bytes in memory. So a structure, or an array, or a single variable, or an array of structures. But not a structure plus an array of ints declared after it which just happens to occupy the next memory

Upvotes: 1

user2100815
user2100815

Reputation:

It's a type that can hold the size (in chars) of the largest chunk of contiguous memory you can possibly allocate. As you observe, objects are made up of pointers and so on, so the actual amount of memory owned by an object could possibly be greater than size_t could represent. However, the size of an object returned by the sizeof operator (which doesn't take into account things like dynamic memory allocations to pointers in an object) must be storable in a size_t.

Upvotes: 3

Related Questions