I'm writing a simple program which makes use of std::map::erase
.
The program is fine, but there is something I do not understand.
If I pass to the erase
function an interval in which the first iterator is beyond the second one, the function does not erase anything. And it is good.
On the other side, if I use std::distance
with the first iterator beyond the second one this function "fails". I know that this is due to the nature of the map's iterator, and for example with std::vector
there is not this problem.
But I do not understand how map::erase
could know whether the interval is valid or not.
From std::distance
's specification:
The behavior is undefined if last is not reachable from first by (possibly repeatedly) incrementing first.
There's an immaterial exception post-C++11 for random access iterators, but this does not apply to maps. This is undefined behavior, so a "failure", or even a crash is what you can get here.
std::map
's erase()
method also seems to indicate that this is undefined behavior, too:
- Removes the elements in the range [first; last), which must be a valid range in *this.
The iterator values you're passing do not comprise a "valid range", hence this is undefined behavior too. Even though today that seems to do nothing, the resulting code is well within its rights if next week your code started crashing, because that's what "undefined behavior" means.
In conclusion, both erase()
and std::distance
result in undefined behavior in this situation.
It doesn't!
It just assumes the range is valid, and you'll only notice it isn't if it not being causes some unexpected symptom.
Whether that occurs or not is completely down to the specifics of the internal implementation and, quite possibly, chance. This is textbook undefined behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With