Yes, as long as you only use ptr_end in comparisons* and don't attempt to deference it, this is fine. Quoting from § 5.7 in the C++11 draft standard regarding additive operations with pointers (emphasis mine):
If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.
Similar provisions are listed for the relational operators in § 5.9:
If two pointers point to elements of the same array or one beyond the end of the array, the pointer to the object with the higher subscript compares higher.
As to whether vector
's buffer counts as an array for the purposes of the above, § 8.3.4 states:
An object of array type contains a contiguously allocated non-empty set of N subobjects of type T.
which is consistent with what § 23.3.6.1 has to say about vector
:
The elements of a vector are stored contiguously
Since pointers are iterator
s, this sort of thing is a handy trick for using standard library algorithms with an arbitrary block of memory as the input. For example, say you want to use the lower_bound
algorithm, but your data is stored in an MFC CArray:
CArray<int> someInts;
// populate and check for empty
int* begin = someInts.GetData();
int* end = begin + someInts.GetSize(); // for bounds-checking only; don't dereference
int* answer = std::lower_bound(begin, end, 100);
*There are a couple other operations that are legal too; e.g. since you know your vector isn't empty, you could subtract one to get a pointer to the last element. The important thing is don't dereference.