In the subsequent quotes, I'm referring to the ISO standard draft N4713.
§ 6.6.3, paragraph 1 says:
...The lifetime of an object o of type T ends when:
...
— the storage which the object occupies is released, or is reused by an object that is not nested within o (6.6.2).
Please answer the questions in the code comments:
#include <new>
int main() {
int x[2] = {0, 1};
char* p = new (x + 1) char{0}; // Has x ended its' lifetime?
int z = x[0]; // Is this UB?
}
If I used unsigned char as array element type, the array object x would have provided storage for the *p, according to § 6.6.2, paragraph 3:
If a complete object is created (8.5.2.4) in storage associated with another object e of type “array of N unsigned char” or of type “array of N std::byte” (21.2.1), that array provides storage for the created object if:
— the lifetime of e has begun and not ended, and
— the storage for the new object fits entirely within e, and
— there is no smaller array object that satisfies these constraints.
Please, validate my statements in the code comments:
#include <new>
int main() {
unsigned char x[2] = {0, 1};
char* p = new (x + 1) char{0}; // Only x[1] have ended its' lifetime.
int z = x[0]; // This is OK.
}
Although I do not understand the last rule in the previous quote, please give an example?
there is no smaller array object that satisfies these constraints.
unsigned charor an array ofstd::byte. Your example has neither (your array if ofint), so that section does not apply.int z = x[0];seems not to be UB, because array-to-pointer conversion and pointer arithmetic don't require an array or its elements to be within their lifetime. And the lifetime ofx[0]hasn't ended, because its storage wasn't reused.