https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91357
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- More specifically: v.operator[](1); /* maybe okay -- forms a pointer one past end */ Not OK. **Dereferences** a past-the end iterator. That's UB. Go to jail. Go directly to jail. Do not pass Go. Do not collect £200. v[1]; /* highly suspicious but not obviously invalid or UB */ UB for the same reason. int *ugly_end = &v[1]; /* hmm. is this okay? */ No. v[1] is UB already, &v[1] doesn't make it unundefined. std::cout << v[1] << std::endl; /* definitely not okay */ v[2]; /* definitely not okay -- merely computing this pointer is UB */ There's no pointer. vector::operator[] is not specified in terms of pointers. This is not C. The assertion is entirely correct. Calling operator[] with an invalid value is UB, it doesn't matter what you do (or don't do) with the result.