treating memory returned by operator new(sizeof(T) * N) as an array

The issue of pointer arithmetic on allocated memory, as in your example:

T* storage = static_cast<T*>(operator new(sizeof(T)*size));
// ...
T* p = storage + i;  // precondition: 0 <= i < size
new (p) T(element);

being technically undefined behaviour has been known for a long time. It implies that std::vector can’t be implemented with well-defined behaviour purely as a library, but requires additional guarantees from the implementation beyond those found in the standard.

It was definitely not the intention of the standards committee to make std::vector unimplementable. Sutter is, of course, right that such code is intended to be well-defined. The wording of the standard needs to reflect that.

P0593 is a proposal that, if accepted into the standard, may be able to solve this problem. In the meantime, it is fine to keep writing code like the above; no major compiler will treat it as UB.

Edit: As pointed out in the comments, I should have stated that when I said storage + i will be well-defined under P0593, I was assuming that the elements storage[0], storage[1], …, storage[i-1] have already been constructed. Although I’m not sure I understand P0593 well enough to conclude that it wouldn’t also cover the case where those elements hadn’t already been constructed.

Leave a Comment

tech