P0137 memperkenalkan templat fungsi std::launder
dan membuat banyak, banyak perubahan pada standar di bagian tentang serikat pekerja, masa pakai, dan petunjuk.
Apa masalah yang dipecahkan makalah ini? Apa saja perubahan pada bahasa yang harus saya ketahui? Dan apa yang akan kita lakukan launder
?
std::launder
?std::launder
digunakan untuk "mendapatkan pointer ke objek yang dibuat dalam penyimpanan yang ditempati oleh objek yang sudah ada dari jenis yang sama, bahkan jika memiliki konst atau referensi anggota."Jawaban:
std::launder
diberi nama tepat, meskipun hanya jika Anda tahu untuk apa itu. Ia melakukan pencucian memori .Perhatikan contoh di koran:
Pernyataan itu melakukan inisialisasi agregat, menginisialisasi anggota pertama
U
dengan{1}
.Karena
n
merupakanconst
variabel, kompiler bebas untuk menganggap bahwau.x.n
harus selalu 1.Jadi apa yang terjadi jika kita melakukan ini:
Karena
X
sepele, kita tidak perlu menghancurkan objek lama sebelum membuat yang baru sebagai gantinya, jadi ini adalah kode hukum yang sempurna. Objek baru akan memilikin
anggotanya menjadi 2.Jadi katakan padaku ... apa yang akan
u.x.n
kembali?Jawaban yang jelas adalah 2. Tapi itu salah, karena kompiler diperbolehkan untuk berasumsi bahwa
const
variabel yang benar-benar (bukan hanya aconst&
, tetapi variabel objek yang dideklarasikanconst
) tidak akan pernah berubah . Tapi kami baru saja mengubahnya.[basic.life] / 8 menjabarkan keadaan saat OK untuk mengakses objek yang baru dibuat melalui variabel / pointer / referensi ke yang lama. Dan memiliki
const
anggota adalah salah satu faktor yang mendiskualifikasi.Jadi ... bagaimana kita bisa bicara dengan
u.x.n
benar?Kita harus mencuci ingatan kita:
Pencucian uang digunakan untuk mencegah orang melacak dari mana Anda mendapatkan uang Anda. Pencucian memori digunakan untuk mencegah kompiler melacak di mana Anda mendapatkan objek Anda, sehingga memaksa untuk menghindari optimasi yang mungkin tidak berlaku lagi.
Faktor lain yang mendiskualifikasi adalah jika Anda mengubah jenis objek.
std::launder
dapat membantu di sini juga:[basic.life] / 8 memberi tahu kami bahwa, jika Anda mengalokasikan objek baru dalam penyimpanan yang lama, Anda tidak dapat mengakses objek baru melalui pointer ke yang lama.
launder
memungkinkan kita untuk melangkah ke samping itu.sumber
n
adalahconst
variabel, kompiler bebas untuk berasumsi bahwau.x.n
akan selalu menjadi 1." Di mana dalam standar yang tertulis di situ? Saya bertanya karena masalah yang Anda tunjukkan tampaknya menyiratkan kepada saya bahwa itu salah sejak awal. Seharusnya hanya benar di bawah aturan seolah-olah, yang gagal di sini. Apa yang saya lewatkan?ptr
diwakilkan, maka Anda mematahkanlaunder
prasyarat, jadi tidak ada gunanya membicarakan hasil.memcpy
menjadi reinterpretasi di tempat pada platform yang didukung (yaitu pelurusan longgar) pula .