Reputation: 61
Can someone explain and provide examples of situations where using size_t
would be more beneficial than, let's say, int
or uint8_t
for array declarations or iteration?
Upvotes: 1
Views: 487
Reputation: 1648
While using size_t
for iteration seems the natural choice, there is at least one pitfall.
Consider the following for-loop:
int arr[]{0, 1, 2, 3};
for(size_t i = 3; i >=0; --i) {
std::cout << i << ": " << arr[i] << std::endl;
}
Expected behavior - at least at first glance, is to get these 4 lines printed:
3: 3
2: 2
1: 1
0: 0
What we get instead is something like:
3: 3
2: 2
1: 1
0: 0
18446744073709551615: -1
18446744073709551614: -2
18446744073709551613: 32514
18446744073709551612: -41561408
[and so on]
That's because size_t a = 0; --a;
on this particular platform results in a
being 18446744073709551615
.
On a vague related note, even harder to spot problems can be introduced by mixing of signed and unsigned types in arithmetic operations and some developers state that using data type size_t
causes more problems than it solves.
Upvotes: 3
Reputation: 84569
Match your type to your data. If you have a counter (that can't be negative) or a length or size, ... then an unsigned
type makes sense, provides double the range of the same size signed type, etc... For counters, lengths, etc.. the standard C++ sizetype is size_t
. Can you use other types -- sure. But in general, size_t
is the preferred sizetype.
If you have an value that is size_t
and need to iterate over the range, use size_t
as your loop counter as well, e.g.
size_t len = mystring.length();
for (size_t i = 0; i < len; i++) { ... }
If you attempt to use a signed loop variable instead, you will generate a Warning: comparison between signed and unsigned types.. So match your types as well.
Upvotes: 7
Reputation: 27577
size_t
is unsigned and large enough to index any container in memory, it's purpose built to use as an index type.
Upvotes: 2