0

I saw an example recently that looks like the following:

const size_t NDim = 3;  
double coords[NDim];

My question is straight forward. When does one use size_t vs an int or unsigned int? In this particular case, wouldn't the following be the equivalent as the above:

const unsigned int NDim = 3;  
double coords[NDim];
Flexo
  • 87,323
  • 22
  • 191
  • 272
randombits
  • 47,058
  • 76
  • 251
  • 433
  • 2
    Using the type name to document the fact that it is the size of something – Ed Heal Apr 20 '16 at 16:55
  • IMHO use `int` unless `int` can't cover the range you want. Then use `long long int`. – NathanOliver Apr 20 '16 at 16:57
  • @NathanOliver Object sizes and array dimensions are specifically meant to be represented with `std::size_t`, so it's good form, and _in theoretical edge cases_ required, to use that in such contexts. For most other things, I would recommend the platform's native word size _but_ defaulting to `unsigned` unless there's a specific need for `signed` values. It just makes sense to me. – underscore_d Apr 20 '16 at 17:04
  • @NathanOliver, care to clarify your point? Why not use the type specifically created for array indexing? – SergeyA Apr 20 '16 at 17:09
  • @underscore_d using [this](http://stackoverflow.com/a/24104825/4342498) answer as a reference as I found it quick. Unsigned sizes was a mistake and even Bjarne Stroustrup has admitted that. Mod 2 behavior is rarely wanted in most cases. – NathanOliver Apr 20 '16 at 17:09
  • @NathanOliver, the linked answer discussess int vs unsigned int. Not int vs size_t. – SergeyA Apr 20 '16 at 17:10
  • @SergeyA It discusses both and says neither is what you want. – NathanOliver Apr 20 '16 at 17:20
  • @underscore_d One of those theoretical cases is when you have an array of `numeric_limits::max()`. In those cases using `size_t` for the index of a loop produces a infinite loop as the index will always be in range. – NathanOliver Apr 20 '16 at 17:21
  • @NathanOliver ...I'll have to go away and think about a clever way to get around that, if any exists. But while we're here, surely a `signed` value is no better there, as you'll be unable to reach the second half of the array? – underscore_d Apr 20 '16 at 19:05
  • @underscore_d If `MAX == numeric_limits::max()` then the loop will never end. Also trying to go backwars `for(size_t = foo; i > 0; --i)` is problematic as you cannot go below 0. IMHO there is no reason to use and unsigned type unless you are doing bitwise operations or you need an overflow guarantee. If you need more space just grab a bigger `int`. A signed `long long int` should work for anything outside of supercomputers. – NathanOliver Apr 20 '16 at 19:05
  • @underscore_d This perfectly highlights my point. If you used a signed integer none of this would matter. You could write `for(big_enough_int = 0; i < some_value; ++i)` and `for(big_enough_int = some_value; i > 0; --i)` and now it is going to do what you want. – NathanOliver Apr 20 '16 at 19:12
  • There seem to be several questions that cover this ground. I don't see anything new introduced by this one. – Adrian McCarthy Apr 20 '16 at 21:05
  • @NathanOliver fwiw, my 2nd example yesterday didn't work either. far as i can tell at the moment, the way to loop over the entire range of an unsigned type is this: http://stackoverflow.com/a/20986451/2757035 this could probably be mangled to work with `for` too, but that seems like unnecessary work. – underscore_d Apr 21 '16 at 17:28

2 Answers2

2

size_t is commonly used for array indexing and loop counting.
According to cppreference:

Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.

It also states:

std::size_t can store the maximum size of a theoretically possible object of any type (including array). A type whose size cannot be represented by std::size_t is ill-formed (since C++14)

Andreas DM
  • 10,685
  • 6
  • 35
  • 62
0

The answer is straightforward as well. You use size_t for all your array indexing and sizing needs, this is exactly what it was designed for. And you never use anything else for it.

Apart from being a self-documenting feature, it also has another important aspect - on many platforms sizeof(int) is not equal to sizeof(size_t).

SergeyA
  • 61,605
  • 5
  • 78
  • 137