views:

165

answers:

4

Possible Duplicate:
When to use std::size_t?

hello.

Assuming usage patterns are the same (i.e. no negative numbers), which is preferable to use for various indexes, int or size_t type?

Is there performance difference in your experience on 64-bit Intel between the two?

Thank you

A: 

The types aren't different in the sense you're implying, and generally int is 32bits, and size_t is the width of the platform word (32-64 bits). I'd suggest you use size_t when dealing with files, buffers, and anything else that might describe an area of memory or a buffer.

Furthermore you should note that int is signed, while size_t is not.

Finally, int was historically used where size_t should be used now. However int is still useful in it's own right for other purposes.

Matt Joiner
thanks.I am trying to standardize in my project on particular type, to enhance interfaces mostly, but also to remove compiler warnings.
aaa
A: 

size_t or ptrdiff_t. int might not be enough to access all the elements of an array.

dan04
@dan04, it is highly unlikely that int won't be enough. More importantly is that the standard containers use size_t, and since int is signed while size_t is unsigned, you can get situations of comparison between signed and unsigned types.
Michael Aaron Safyan
@Michael Aaron Safyan: Quite the opposite, `int` is basically guaranteed to be insufficient in general case, since it is *signed*, i.e. it wastes one bit for the sign.
AndreyT
@AndreyT, in theory, yes, but in practice, when do you really have an array that size loaded into RAM? If you have that much loaded into RAM, there is probably something wrong with your design (you should probably be streaming data and using iterators), or you should worry about the type... but for almost all practical situations, you are going to be dealing with much smaller arrays.
Michael Aaron Safyan
+2  A: 

It depends on what you are doing. If you are iterating over a vector, then use std::size_t:

for (std::size_t i = 0; i < vec.size(); i++) {
   // do something with vec[i]
}

However, beware of coding errors such as:

for (std::size_t i = 99; i >= 0; i--) {
   // This is an infinite loop
}

If you are just doing a loop, you might want to use just a plain int because of the situation above. There should be no performance difference between using int and std::size_t. If you need an exact size, then you should use neither int nor size_t, but rather the types defined in stdint.h.

Michael Aaron Safyan
It you are iterating over a `std::vector<>` (or any other standard container) you might want to use `std::vector<>::size_type` instead of shortcutting directly to `std::size_t`.
AndreyT
@AndreyT, if one is concerned about genericity, then one should really use iterators. If one is whipping up a quick function that iterates over a vector, then there is nothing to gain from the more verbose std::vector::size_type in place of std::size_t.
Michael Aaron Safyan
+2  A: 

size_t is the type that should be used for array indexing when you work with a relatively generic arrays. I.e. when you have just an array of abstract chars, ints or something else.

When you are working with a specific array, i.e. an array that contains some elements specific for your application, you should normally already have a "type of choice" to count or to index the entities of that type in your application. That's the type you should use. For example, if some array contains the records for company employees, then you should already have a "type of choice" in your program that you use to designate the "quantity of employees". That's the type you should use for indexing arrays of employee records. It could be unsigned int, it could be employee_count_t or something like that. Using a naked size_t for that purpose is a design error.

Note also, that size_t is a type not immediately intended for array indexing. It is a type intended to represent the size of the largest object in the program. It "works" for arrays by transitivity: arrays are objects, hence size_t is always enough to index an array. However, when you design a program it makes more sense to think in terms of generic containers, instead of thinking in terms of specific arrays. Today it might be an array, tomorrow you might have to switch to a linked list or a tree instead. In general case, the range of size_t is not sufficient to represent the number of elements in an abstract container, which is why size_t in such cases is not a good choice.

AndreyT
@AndreyT, if tomorrow it could be a linked list or tree, then an index of any type at all is no good. For that, you need iterators.
Michael Aaron Safyan
@Michael Aaron Safyan: Not necessarily. It is possible to build a segmented array of some sort, for which the concept of index still makes sense, and which nevertheless is not limited by the maximum size of a continuous memory block.
AndreyT
@AndreyT, but linked lists don't support random access... this is getting very hackish and will likely have very poor performance. The most general solution is to use iterators or visitors. Indices only make sense for random-access containers.
Michael Aaron Safyan
@Michael Aaron Safyan: Firstly, as I said, one can build a *random-access* container, which is not limited by the size of the maximum contiguous memory block, some "segmented array" being one example. Secondly, whether the performance of indices with lists is good or not depends on the context. They might be too slow for routine direct access, but they might be required for serialization.
AndreyT
Huh? How would they be required for serialization? Also, making a function a part of the API encourages people to use it... if it is going to be slow, it should probably never be made a part of the API in the first place. One can easily seek to an arbitrary point by repeatedly stepping linearly, and forcing the user to do this will let them know just how ugly and inefficient it is... if there is a simple operator[] overload, a user will probably not think twice about it and assume it is a reasonably efficient operation.
Michael Aaron Safyan
@Michael Aaron Safyan: Firstly, they would be required for serialization in one (if not the only) viable approach of serializing references into a linked list. Pointers are converted to indices and vise versa. Secondly, nobody besides you is talking about making any API functions (like `operator[]`) for that purpose. My point is simple: indexing is absolutely needed when working with linked lists in certain contexts, and there's nothing inefficient about indexing linked lists if done properly.
AndreyT
@AndreyT, that still doesn't make sense. You could just keep a counter that you increment as you step through the linked list. Anyway, this isn't worth arguing, especially without example code to discuss, as we might not be arguing the same thing.
Michael Aaron Safyan
@Michael Aaron Safyan: That's exactly what I'm talking about: you can just keep a counter as you step through the list. Now, let's get back to the original issue: what type are you going to use for that counter? All I'm saying is that in general case `size_t` is not sufficient.
AndreyT