Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is pointer arithmetic on allocated storage UB?

Let's say I want to implement std::vector without invoking any undefined behavior (UB). Is the code below invokes UB:

struct X{int i;};
int main(){
  auto p = static_cast<X*>(::operator new(sizeof(X)*2));
  new(p) X{};
  new(p+1) X{};// p+1 UB?
}

Folowing a selection of quote from the standard that may help:

[basic.stc.dynamic.allocation]

The pointer returned (by an allocation function) shall be suitably aligned so that it can be converted to a pointer to any suitable complete object type (21.6.2.1) and then used to access the object or array in the storage allocated (until the storage is explicitly deallocated by a call to a corresponding deallocation function).

[expr.add]

When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i + j] if 0<=i + j<=n; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i − j] if 0<=i − j <=n; otherwise, the behavior is undefined.

My interpretation is that allocation provides an possibly-hypothetical array of X (in C++ arrays are objects) so pointer arithmetic on allocated storage as in the exemple may not invoke undefined behavior. Or my interpretation of hypothetical is wrong? How could I do if the previous code snipest is UB?

like image 220
Oliv Avatar asked Apr 23 '26 02:04

Oliv


1 Answers

Yes, technically it has undefined behaviour, though we tend to ignore that. P0593 should fix it properly.

The phrase "possibly-hypothetical" refers to one-past-the-end "elements" (ref), and does not permit this case.

like image 130
Lightness Races in Orbit Avatar answered Apr 25 '26 15:04

Lightness Races in Orbit