Pertimbangkan tiga structs berikut :
class blub {
int i;
char c;
blub(const blub&) {}
};
class blob {
char s;
blob(const blob&) {}
};
struct bla {
blub b0;
blob b1;
};
Pada platform tipikal di mana int4 byte, ukuran, pelurusan dan total padding 1 adalah sebagai berikut:
struct size alignment padding
-------- ------ ----------- ---------
blub 8 4 3
blob 1 1 0
bla 12 4 6
Tidak ada tumpang tindih antara penyimpanan blubdan blobanggota, meskipun ukuran 1 blobpada prinsipnya "pas" di padding blub.
C ++ 20 memperkenalkan no_unique_addressatribut, yang memungkinkan anggota kosong yang berdekatan untuk berbagi alamat yang sama. Ini juga secara eksplisit memungkinkan skenario yang dijelaskan di atas menggunakan padding dari satu anggota untuk menyimpan yang lain. Dari cppreference (penekanan saya):
Menunjukkan bahwa anggota data ini tidak perlu memiliki alamat yang berbeda dari semua anggota data non-statis lainnya di kelasnya. Ini berarti bahwa jika anggota memiliki tipe kosong (misalnya Allocator stateless), kompiler dapat mengoptimalkannya agar tidak menempati ruang, sama seperti jika itu adalah basis kosong. Jika anggota tidak kosong, bantalan ekor di dalamnya dapat juga digunakan kembali untuk menyimpan anggota data lainnya.
Memang, jika kita menggunakan atribut ini pada blub b0, ukuran blatetes 8, sehingga blobmemang disimpan dalam blub seperti yang terlihat pada godbolt .
Akhirnya, kita sampai pada pertanyaan saya:
Teks apa dalam standar (C ++ 11 hingga C ++ 20) yang mencegah tumpang tindih ini no_unique_address, untuk objek yang tidak dapat disalin secara sepele?
Saya perlu mengecualikan objek trivially copyable (TC) dari atas, karena untuk objek TC, diperbolehkan std::memcpydari satu objek ke yang lain, termasuk sub-objek anggota, dan jika penyimpanan tumpang tindih ini akan pecah (karena semua atau sebagian dari penyimpanan untuk anggota yang berdekatan akan ditimpa) 2 .
1 Kami menghitung padding hanya sebagai perbedaan antara ukuran struktur dan ukuran semua anggota konstituennya, secara rekursif.
2 Inilah sebabnya mengapa saya memiliki salinan konstruktor yang didefinisikan: untuk membuat blubdan blobtidak dapat disalin secara sepele .