Implementing a std::vector like container without undefined behavior

This is topic that is under active discussion, we can see this in the proposal p0593: Implicit creation of objects for low-level object manipulation. This is a pretty solid discussion of the issues and why they are not fixable without changes. If you have different approaches or strong views on the approaches being considered you may want to reach out to the proposals authors.

It includes this discussion:

2.3. Dynamic construction of arrays

Consider this program that attempts to implement a type like std::vector (with many details omitted for brevity):

….

In practice, this code works across a range of existing
implementations, but according to the C++ object model, undefined
behavior occurs at points #a, #b, #c, #d, and #e, because they attempt
to perform pointer arithmetic on a region of allocated storage that
does not contain an array object.

At locations #b, #c, and #d, the arithmetic is performed on a char*,
and at locations #a, #e, and #f, the arithmetic is performed on a T*.
Ideally, a solution to this problem would imbue both calculations with
defined behavior.

  1. Approach

The above snippets have a common theme: they attempt to use objects that they never created. Indeed, there is a family of types for which programmers assume they do not need to explicitly create objects. We propose to identify these types, and carefully carve out rules that remove the need to explicitly create such objects, by instead creating them implicitly.

The approach using the adc union has the problem that we expect to be able to access the contained data via a pointer T* i.e. via std::vector::data. Accessing the union as a T* would violate the strict aliasing rules and therefore be undefined behavior.

Leave a Comment