Stroustrup and overflowing size_type in a loop

I am reading Bjarne Straustup's "Principles and Practices of Programming Using C ++" and I need to clarify the amazing bit that I found in section 25.5.3. The author claims that if we want to iterate over std::vector , then using a loop variable, for example

 for (vector<int>::size_type i = 0; i < v.size(); ++i) 

less secure than using iterators for the vector class:

 for (vector<int>::iterator p = v.begin(); p != v.end(); ++p) 

because, being an unsigned type, i can overflow. He argues that a loop using iterators does not have such a limitation. I'm a bit confused, as I found out that size_type guaranteed to be large enough to represent the largest possible vector, so a variable of type size_type will never overflow in such a loop.

EDIT

To be more specific, he presents an example using a loop variable of type int in front of two others, and then at the end he states:

" size_type guaranteed to be unsigned, so the first (unsigned integer) form has one more bit to play than the previous version of int . It can be significant, but it still gives only one bit of range (doubling the number of iterations that can be performed ). An iterator loop has no such limitation. "

Does not return vector<T>::size() a vector<T>::size_type ? I do not see any restrictions.

+6
source share
2 answers

Well, yes, the paragraph you quoted seems to imply or imply that size_type can be problematic. But I do not think that this was the intention of the author.

Note that the previous paragraph says (re: second edition)

So, technically, most of the loops in this book were sloppy [...]. To avoid this problem, we can use the size_type provided by vector , iterators, or the for -statement range:

This paragraph, size_type provides a solution for the potentially problematic int loops used in the previous sections of the book. It is referred to as a safe alternative along with an iterator or range for the loop version.


The problem of potential overflow (or insufficient range) exists when someone tries to use std::size_t to count or index the elements of a container based on a non-array, for example std::list , std::deque , std::map , etc. ., instead of using the size_type container. But this is a slightly different story, even if it is connected.

+6
source

vector::size returns vector::size_type , so vector::size_type i starting at 0 cannot exceed the maximum value represented by vector::size_type before exceeding the value returned by vector::size . It is safe.


because, being unsigned, I could overflow.

If this is a direct quote, then this is a mistake and is corrected in the second edition, where i is int . In this case, i may overflow.


Why is it worth it, I do not find (2nd edition) that part in which Bjarne claims that he is safer than the other.

He claims that iterators do not have the range limit that indexes have. And it is true. Iterators can theoretically support infinitely large ranges.

Using size_type for cyclic container elements does not have overflow problems, but the fact that the container interface supports size_type primarily leads to the fact that choosing size_type limits the range of elements that the container can contain.

+4
source

Source: https://habr.com/ru/post/1015567/


All Articles