Using auto is risky

Can you spot a problem with the following code?

1
2
3
4
vector<int> vec {1, 2, 3, 4, 5};
for (auto i = vec.size() - 1; i >= 0; --i) {
cout << vec[i] << endl;
}

What we want to achieve here is to reversely traverse a vector, i.e., we want the output to be

1
2
3
4
5
5
4
3
2
1

However, when we define i in the for-loop, we lazily used auto, i.e., the type of i is dictated by the type of vec.size().
Note that the type of vec.size() is unsinged long. When i hits $0$, i is decremented to $-1$. By two’s complement, $-1$ is a bunch of $1$’s in the front, and therefore by unsigned representation, it will be a gigantic number. Hence, the for-loop condition will always satisfy. More importantly, vec will most likely not have that large index.