If I understand their lifetime rules correctly, that any non-const operation invalidates pointers, then I think this is actually quite strict. Maybe too strict! For instance, does operator[]
invalidate pointers? Heck, how about begin()
and end()
- can these iterators coexist if one call invalidates the other?
Such broad invalidation would break a lot of <algorithm>
, if you can't grab a pair of iterators, so I feel I must be missing something. But without inter-function analysis or additional annotation, there's no difference to the caller between say insert()
which needs to invalidate and begin()
/end()
which need not.
(He did cover the paired lifetimes of input iterators to insert()
, but that's not what I'm talking about because those are const, so acquiring them simultaneously is fine. e.g. cbegin()
/cend()
)
I also posted this concern on /r/cpp, but I probably missed the conversation by now. Hopefully you smart folks here can either set me straight or agree this is problematic.
Anyway, I think it's interesting how close these proposed C++ pointer invalidations are to Rust borrowing, solving some of the same problems, but resulting in opposite error reporting.
let mut v = vec![1, 2, 3];
let x = &mut v[0];
v.push(4); // error: cannot borrow `v` as mutable more than once at a time
*x = 42;
vector<int> v { 1, 2, 3 };
int *x = &v[0];
v.push_back(4);
*x = 42; // ERROR, invalidated by push_back
i.e. Rust complains if you try to invalidate a reference; C++ Core complains if you try to use the invalidated pointer. Both recognize the problem, but place different blame.