Dans la norme C ++ 20, il est dit que les types de tableau sont de type implicite à vie .
Cela signifie-t-il qu'un tableau d'un type de durée de vie non implicite peut être créé implicitement? La création implicite d'un tel tableau ne provoquerait pas la création des éléments du tableau?
Considérez ce cas:
//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");
Ce code n'est-il plus UB depuis C ++ 20?
Peut-être que c'est mieux ainsi?
//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 the array of 10 std::string"
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");
Réponses:
Oui.
Oui.
C'est ce qui rend
std::vector
implémentable en C ++ ordinaire.la source
std::launder(static_cast<std::string*>(ptr))
ne renvoie pas de pointeur sur le premier élément du tableau car il ne fait pas partie de sa durée de vie, mais qu'ilstd::launder(static_cast<std::string(*)[10]>(ptr))
renvoie un pointeur sur le tableau, car le tableau est compris dans sa durée de vie?std::launder
n'est pas réellement nécessaire, car eel.is/c++draft/intro.object#11 garantit queptr
cela pointera déjà vers le tableau?static_cast
tostd::string (*) [10]
devrait donc suffire! tx.std::launder
sera bien défini. Il n'y a aucunstd::string
objet versptr
lequel pointer, mais pourrait pointer vers le tableau, de sorte que le transtypage statique laissera la valeur inchangée etsptr
pointera également vers le tableau. Avecstd::launder
elle, UB est simplement à cause desstd::launder
exigences de.