tags:

views:

1258

answers:

11

Hi,

I'm just wondering should I use std::size_t for loops and stuff instead of int? For instance:

#include <cstdint>

int main()
{
    for (std::size_t i = 0; i < 10; ++i)
        // std::size_t OK here? Or should I use, say, unsigned int instead?
}

In general, what is the the best practice regarding when to use std::size_t?

A: 

size_t is unsigned int. so whenever you want unsigned int you can use it.

I use it when i want to specify size of the array , counter ect...

void * operator new (size_t size); is a good use of it.
Ashish
Actually it's not necessarily the same as unsigned int. It *is* unsigned, but it might be larger (or I guess smaller though I don't know of any platforms where this is true) than an int.
tgamblin
+3  A: 

By definition, size_t is the result of the sizeof operator. size_t was created to refer to sizes.

The number of times you do something (10, in your example) is not about sizes, so why use size_t? int, or unsigned int, should be ok.

Of course it is also relevant what you do with i inside the loop. If you pass it to a function which takes an unsigned int, for example, pick unsigned int.

Daniel Daranas
+17  A: 

A good rule of thumb is for anything that you need to compare in the loop condition against something that is naturally a std::size_t itself.

std::size_t is the type of any sizeof expression and as is guaranteed to be able to express the maximum size of any object (including any array) in C++. By extension it is also guaranteed to be big enough for any array index so it is a natural type for a loop by index over an array.

If you are just counting up to a number then it may be more natural to use either the type of the variable that holds that number or an int or unsigned int (if large enough) as these should be a natural size for the machine.

Charles Bailey
It's worth mentioning that *not* using `size_t` when you should can lead to [security bugs](http://stackoverflow.com/questions/3259413/should-you-always-use-int-for-numbers-in-c-even-if-they-are-non-negative/3261019#3261019).
BlueRaja - Danny Pflughoeft
+10  A: 

size_t is the result type of the sizeof operator.

Use size_t for variables that model size or index in an array. size_t conveys semantics: you immediately know it represents a size in bytes or an index, rather than just another integer.

Also, using size_t to represent a size in bytes helps making the code portable.

Gregory Pakosz
+1  A: 

size_t is a very readable way to specify the size dimension of an item - length of a string, amount of bytes a pointer takes, etc. It's also portable across platforms - you'll find that 64bit and 32bit both behave nicely with system functions and size_t - something that unsigned int might not do (e.g. when should you use unsigned long

Ofir
+4  A: 

Use std::size_t for indexing/counting C-style arrays.

For STL containers, you'll have (for example) vector<int>::size_type, which should be used for indexing and counting vector elements.

In practice, they are usually both unsigned ints, but it isn't guaranteed, especially when using custom allocators.

Peter Alexander
With gcc on linux, `std::size_t` is usually `unsigned long` (8 bytes on 64 bits systems) rather than `unisgned int` (4 bytes).
rafak
C-style arrays are not indexed by `size_t` though, since the indexes can be negative. One could use `size_t` for one's own instance of such an array if one doesn't want to go negative, though.
Johannes Schaub - litb
Are comparisons on u64s as fast as comparisons on u32s? I've timed severe performance penalties for using u8s and u16s as loop sentinels, but I don't know if Intel has gotten their act together on 64s.
Crashworks
Since C-style array indexing is equivalent to using operator `+` on pointers, it would seem that `ptrdiff_t` is the one to use for indices.
Pavel Minaev
As for `vector<T>::size_type` (and ditto for all other containers), it's actually rather useless, because it is effectively guaranteed to be `size_t` - it's typedef'd to `Allocator::size_type`, and for restrictions on that with respect to containers see 20.1.5/4 - in particular, `size_type` must be `size_t`, and `difference_type` must be `ptrdiff_t`. Of course, the default `std::allocator<T>` satisfies those requirements. So just use the shorter `size_t` and don't bother with the rest of the lot :)
Pavel Minaev
A: 

The size_t type is meant to specify the size of something so it's natural to use it, for example, getting the length of a string and then processing each character:

for (size_t i = 0; i < strlen (str); i++)
    str[i]++;

You do have to watch out for boundary conditions of course, since it's an unsigned type. The boundary at the top end is not usually that important since the maximum is usually large (though it is possible to get there). Most people just use an int for that sort of thing because they rarely have structures or arrays that get big enough to exceed the capacity of that int.

But watch out for things like:

for (size_t i = strlen (str) - 1; i >= 0; i--)

which will cause an infinite loop due to the wrapping behavior of unsigned values (although I've seen compilers warn against this).

paxdiablo
A: 

size_t is unsigned int. It used to hide the platform details.

atrane
A: 

size_t is an unsigned type that can hold maximum integer value for your architecture, so it is protected from integer overflows due to a sign (signed int 0x7FFFFFFF incremented by 1 will give you -1) or short size (unsigned short int 0xFFFF incremented by 1 will give you 0).

It is mainly used in array indexing/loops/address arithmetic and so on. Functions like memset() and alike accept size_t only, 'cuz theoretically you may have aa block of memory of size 2^32 -1 (on 32bit platform).

For such simple loops don't bother and use just int.

Wizzard
A: 

size_t is an unsigned integral type, that can represent the largest integer on you system. Only use it if you need very large arrays,matrices etc.

Some functions return an size_t and your compiler will warn you if you try to do comparisons.

Avoid that by using a the appropriate signed/unsigned datatype or simply typecast for a fast hack.

monkeyking
+1  A: 

See About size_t and ptrdiff_t

The article will help the readers understand what size_t and ptrdiff_t types are, what they are used for and when they must be used. The article will be interesting for those developers who begin creation of 64-bit applications where use of size_t and ptrdiff_t types provides high performance, possibility to operate large data sizes and portability between different platforms.

Andrey Karpov