Apakah pointer aritmatika pada penyimpanan yang dialokasikan diizinkan sejak C ++ 20?


10

Dalam standar C ++ 20, dikatakan bahwa tipe array adalah tipe seumur hidup implisit .

Apakah ini berarti bahwa array ke tipe seumur hidup non-implisit dapat dibuat secara implisit? Pembuatan implisit array seperti itu tidak akan menyebabkan pembuatan elemen array?

Pertimbangkan kasus ini:

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

Apakah kode ini bukan lagi UB sejak C ++ 20?


Mungkin cara ini lebih baik?

//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
Saya baru saja melakukan pencarian melalui (draft) standar C ++ 20, dan tidak menemukan apa pun yang menggambarkan array sebagai "tipe seumur hidup implisit" (dan, ya, saya mencari variasi). Harap berikan uraian lebih rinci tentang klaim Anda (mis. Bagian dan klausa dalam standar). Agak sulit untuk menjawab pertanyaan Anda tanpa dapat menemukan sumbernya, apalagi konteks yang relevan.
Peter

1
@ Peter: eel.is/c++draft/basic.types#9 , kalimat terakhir
geza

Saya sedang melihat PDF open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf (seolah-olah draft kerja terbaru) dan bahkan tidak memiliki kalimat itu. Sepertinya Anda harus menemukan arti "seumur hidup implisit" juga. Saya menduga tautan Anda mungkin telah mengambil beberapa "suntingan sedang berlangsung" yang bahkan belum membuatnya menjadi konsep kerja yang dirilis.
Peter

1
@ Peter Perubahan adalah hasil dari P0593 yang digabungkan ke dalam standar dari pertemuan Praha baru-baru ini. Mereka belum merilis draft yang dihasilkan, tetapi Anda dapat melihat kata-kata yang digabungkan dalam komit ini .
walnut

Jawaban:


3

Apakah ini berarti bahwa array ke tipe seumur hidup non-implisit dapat dibuat secara implisit?

Iya.

Pembuatan implisit array seperti itu tidak akan menyebabkan pembuatan elemen array?

Iya.

Inilah yang membuat std::vectorimplementable dalam C ++ biasa.


Bisakah Anda mengonfirmasi juga bahwa std::launder(static_cast<std::string*>(ptr))tidak mengembalikan pointer ke elemen pertama array karena tidak dalam masa pakainya, tetapi std::launder(static_cast<std::string(*)[10]>(ptr))mengembalikan pointer ke array, karena array berada dalam masa pakainya?
Oliv

Sepertinya itu benar bagi saya.
TC

@ Eliv Dan saya kira std::laundersebenarnya tidak diperlukan, karena eel.is/c++draft/intro.object#11 menjamin bahwa ptrsudah akan mengarah ke array?
walnut

@walnut, saya melewatkan itu. Jadi static_castuntuk std::string (*) [10]harus cukup! tx.
Oliv

@ Eliv Tapi saya kira pertanyaannya kemudian menjadi apakah contoh pertama Anda tanpa std::launderakan didefinisikan dengan baik. Tidak ada std::stringobjek untuk menunjuk, tetapi ptrbisa menunjuk ke array, sehingga pemain statis akan meninggalkan nilai tidak berubah dan sptrakan menunjuk ke array juga. Dengan std::launderitu adalah UB hanya karena std::launderpersyaratan.
walnut
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.