Is pointer arithmetic on allocated storage allowed since C++20?

Viewed 447

In the C++20 standard, it is said that array types are implicit lifetime type.

Does it mean that an array to a non implicit lifetime type can be implicitly created? The implicit creation of such an array would not cause creation of the array's elements?

Consider this case:

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (which object?)
std::string * sptr = std::launder(static_cast<std::string*>(ptr));
//pointer arithmetic on not created array elements well defined?
new (sptr+1) std::string("second element");

Is this code not UB any more since C++20?


Maybe this way is better?

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (actually not necessary)
std::string (* sptr)[10] = std::launder(static_cast<std::string(*)[10]>(ptr));
//pointer arithmetic on an array is well defined
new (*sptr+1) std::string("second element");

TC Answer + Comments conclusion:

  1. Array elements are not created but the array is created
  2. The use of launder in the first example cause UB, and is not necessary in the second example.

The right code is:

    //implicit creation of an array of std::string 
    //but not the std::string elements:
    void * ptr = operator new(sizeof (std::string) * 10);
    //the pointer already points to the implicitly created object
    //so casting is enough 
    std::string (* sptr)[10] = static_cast<std::string(*)[10]>(ptr);
    //pointer arithmetic on an array is well defined
    new (*sptr+1) std::string("second element");
1 Answers

Does it means that an array to a non implicit lifetime type can be implicitly created?

Yes.

The implicit creation of such an array would not cause creation of the array's elements?

Yes.

This is what makes std::vector implementable in ordinary C++.

Related