L'aritmetica del puntatore sull'archiviazione allocata è consentita dal C ++ 20?


10

Nello standard C ++ 20, si dice che i tipi di array sono il tipo di durata implicita .

Significa che un array per un tipo di vita non implicito può essere creato in modo implicito? La creazione implicita di un tale array non provocherebbe la creazione degli elementi dell'array?

Considera questo 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");

Questo codice non è più UB dal C ++ 20?


Forse in questo modo è meglio?

//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
Ho appena fatto una ricerca attraverso lo standard (bozza) C ++ 20 e non ho trovato nulla che descriva le matrici come un "tipo di vita implicito" (e, sì, ho cercato varianti). Fornisci una descrizione più dettagliata del reclamo (ad es. Sezione e clausola nella norma). Un po 'difficile rispondere alla tua domanda senza essere in grado di trovare la fonte, figuriamoci qualsiasi contesto rilevante.
Peter


Stavo guardando il PDF open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf (apparentemente l'ultima bozza di lavoro) e non ha nemmeno quella frase. Sembra che dovrai trovare anche il significato di "vita implicita". Ho il sospetto che il tuo link potrebbe aver raccolto alcune "modifiche in corso" che non sono nemmeno state trasformate in bozze di lavoro rilasciate.
Peter,

1
@Peter Le modifiche sono il risultato della fusione di P0593 nello standard della recente riunione di Praga. Non hanno ancora rilasciato la bozza risultante, ma puoi vedere la formulazione unita in questo commit .
Noce

Risposte:


3

Significa che è possibile creare in modo implicito un array per un tipo di vita non implicito?

Sì.

La creazione implicita di un tale array non provocherebbe la creazione degli elementi dell'array?

Sì.

Questo è ciò che rende std::vectorimplementabile in C ++ ordinario.


Potresti confermare anche che std::launder(static_cast<std::string*>(ptr))non restituisce un puntatore al primo elemento dell'array perché non rientra nel suo ciclo di vita, ma che std::launder(static_cast<std::string(*)[10]>(ptr))restituisce un puntatore all'array, perché l'array è nel suo ciclo di vita?
Oliv

Mi sembra corretto.
TC

@Oliv E suppongo che std::laundernon sia effettivamente necessario, perché eel.is/c++draft/intro.object#11 garantisce che ptrindicherà già l'array?
Noce

@walnut, l'ho perso. Quindi un static_casta std::string (*) [10]dovrebbe essere sufficiente! tx.
Oliv

@Oliv Ma immagino che la domanda diventi allora se il tuo primo esempio senza la std::laundervolontà sarà ben definito. Non esiste alcun std::stringoggetto a cui puntare, ma ptrpotrebbe puntare all'array, in modo che il cast statico lascerà invariato il valore e sptrpunterà anche sull'array. Con std::launderesso è UB semplicemente a causa dei std::launderrequisiti.
Noce
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.