Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe in C++ to derive a pointer from std::aligned_storage before using it? [duplicate]

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");
like image 357
Oliv Avatar asked Nov 15 '22 19:11

Oliv


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++.

like image 181
T.C. Avatar answered Dec 28 '22 08:12

T.C.