¿Se permite la aritmética del puntero en el almacenamiento asignado desde C ++ 20?


10

En el estándar C ++ 20, se dice que los tipos de matriz son de tipo implícito de por vida .

¿Significa que se puede crear implícitamente una matriz a un tipo de vida no implícito? ¿La creación implícita de tal matriz no causaría la creación de los elementos de la matriz?

Considere este caso:

//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");

¿Este código ya no es UB desde C ++ 20?


Tal vez de esta manera es mejor?

//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");

1
Acabo de hacer una búsqueda a través del estándar (borrador) C ++ 20, y no encontré nada que describa las matrices como un "tipo de vida implícito" (y, sí, busqué variaciones). Proporcione una descripción más detallada de su reclamo (por ejemplo, sección y cláusula en el estándar). Es difícil responder a su pregunta sin poder encontrar la fuente, y mucho menos cualquier contexto relevante.
Peter

1
@Peter: eel.is/c++draft/basic.types#9 , última oración
geza

Estaba mirando el PDF open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf (aparentemente el último borrador de trabajo) y ni siquiera tiene esa oración. Parece que también necesitarás encontrar el significado de "vida implícita". Sospecho que su enlace puede haber recogido algunas "ediciones en progreso" que ni siquiera han llegado a borradores de trabajo publicados.
Peter

1
@ Peter Los cambios son el resultado de la fusión de P0593 con el estándar de la reciente reunión de Praga. Todavía no han publicado el borrador resultante, pero puede ver la redacción combinada en esta confirmación .
nogal

Respuestas:


3

¿Significa que se puede crear implícitamente una matriz a un tipo de vida no implícito?

Si.

¿La creación implícita de tal matriz no causaría la creación de los elementos de la matriz?

Si.

Esto es lo que hace que sea std::vectorimplementable en C ++ ordinario.


¿Podría confirmar también que std::launder(static_cast<std::string*>(ptr))no devuelve un puntero al primer elemento de la matriz porque no está dentro de su vida útil, sino que std::launder(static_cast<std::string(*)[10]>(ptr))devuelve un puntero a la matriz porque la matriz está dentro de su vida útil?
Oliv

Eso me parece correcto.
TC

@Oliv Y supongo std::launderque no se necesita realmente, porque eel.is/c++draft/intro.object#11 garantiza que ptrya apuntará a la matriz.
nogal

@walnut, me perdí eso. ¡Entonces un static_casta std::string (*) [10]debería ser suficiente! tx.
Oliv

@Oliv Pero supongo que la pregunta es si tu primer ejemplo sin el std::launderestará bien definido. No hay ningún std::stringobjeto al que apuntar, pero ptrpodría apuntar a la matriz, de modo que la conversión estática dejará el valor sin cambios y también sptrapuntará a la matriz. Con std::launderesto es UB simplemente por std::launderlos requisitos de.
nogal
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.