I thought &*vector::end()
was undefined behavior... until I saw some post refer to Stroustrup\'s code:
void vector_pointer_test(element_t* first
It's undefined behaviour. That is, behaviour not defined by the C++ standard. It may be defined by the implementation. More likely, it will happen to work by chance in some situations and not others.
In this case, if the iterator is a raw pointer the compiler will likely optimise &*i into a no-op, so it will likely work. Stroustrup may have known his vector used raw pointers as iterators.
Even if the compiler doesn't optimise it away, in practice, it's only likely to fail if the vector's memory happens to be allocated to end at a segment boundary. (Or if the iterator implementation is written to check for being non-dereferenceable, eg for debugging purposes.)
In C++11 this should be written as:
sort(container.data(), container.data()+container.size());
It's not necessarily undefined behavior, but it depends on the specific implementation of the iterator:
C++03 24.1/5 Iterator requirements
Just as a regular pointer to an array guarantees that there is a pointer value pointing past the last element of the array, so for any iterator type there is an iterator value that points past the last element of a corresponding container. These values are called past-the-end values. Values of an iterator i for which the expression *i is defined are called dereferenceable. The library never assumes that past-the-end values are dereferenceable.
The code in question has undefined behavior if container.end()
is not dereferenceable. Many times a vector's iterator will simply be a pointer - in those cases there's no undefined behavior.