Kebingungannya adalah bahwa C secara eksplisit memungkinkan jenis-menghukum melalui serikat pekerja, sedangkan C ++ (c ++ 11) tidak memiliki izin seperti itu.
c11
6.5.2.3 Struktur dan anggota serikat
95) Jika anggota yang digunakan untuk membaca konten objek penyatuan tidak sama dengan anggota yang terakhir digunakan untuk menyimpan nilai dalam objek, bagian yang sesuai dari representasi objek dari nilai ditafsirkan kembali sebagai representasi objek di objek baru. ketik seperti yang dijelaskan dalam 6.2.6 (proses yang kadang-kadang disebut '' type punning ''). Ini mungkin representasi jebakan.
Situasi dengan C ++:
c ++ 11
9.5 Serikat [class.union]
Dalam serikat pekerja, paling banyak salah satu anggota data non-statis dapat aktif kapan saja, yaitu, nilai paling banyak dari satu anggota data non-statis dapat disimpan dalam serikat kapan saja.
C ++ nantinya memiliki bahasa yang mengizinkan penggunaan serikat yang berisi struct
s dengan urutan awal umum; Namun ini tidak mengizinkan hukuman jenis.
Untuk menentukan apakah jenis serikat hukuman yang diperbolehkan dalam C ++, kita harus mencari lebih lanjut. Ingat ituc99 adalah referensi normatif untuk C ++ 11 (dan C99 memiliki bahasa yang mirip dengan C11 yang memungkinkan penghukuman jenis serikat):
3.9 Jenis [basic.types]
4 - Representasi objek dari objek tipe T adalah urutan objek char unsigned N yang diambil oleh objek tipe T, di mana N sama dengan sizeof (T). Representasi nilai dari suatu objek adalah sekumpulan bit yang menyimpan nilai tipe T. Untuk tipe yang dapat disalin secara trivial, representasi nilai adalah sekumpulan bit dalam representasi objek yang menentukan nilai, yang merupakan salah satu elemen diskrit dari implementasi- set nilai yang ditentukan. 42
42) Maksudnya adalah bahwa model memori C ++ kompatibel dengan yang dari Bahasa Pemrograman ISO / IEC 9899 C.
Ini menjadi sangat menarik ketika kita membaca
3.8 Obyek seumur hidup [basic.life]
Umur objek tipe T dimulai ketika: - penyimpanan dengan perataan dan ukuran yang tepat untuk tipe T diperoleh, dan - jika objek memiliki inisialisasi non-sepele, inisialisasi lengkap.
Jadi untuk tipe primitif (yang ipso facto memiliki inisialisasi sepele) yang terkandung dalam persatuan, umur objek mencakup setidaknya masa perserikatan itu sendiri. Ini memungkinkan kita untuk memohon
3.9.2 Jenis senyawa [basic.compound]
Jika objek tipe T terletak di alamat A, pointer tipe cv T * yang nilainya adalah alamat A dikatakan menunjuk ke objek itu, terlepas dari bagaimana nilai itu diperoleh.
Dengan asumsi bahwa operasi yang kami minati adalah tipe-punning yaitu mengambil nilai anggota serikat yang tidak aktif, dan diberikan sesuai dengan di atas bahwa kami memiliki referensi yang valid ke objek yang dirujuk oleh anggota tersebut, operasi itu bernilai rendah untuk -nilai konversi:
4.1 Konversi nilai-ke-nilai [conv.lval]
Glvalue tipe non-fungsi, non-array T
dapat dikonversi ke nilai awal. Jika T
merupakan tipe yang tidak lengkap, program yang memerlukan konversi ini tidak terbentuk dengan baik. Jika objek yang dirujuk oleh glvalue bukanlah objek bertipe T
dan bukan objek bertipe berasal T
, atau jika objek tidak diinisialisasi, program yang mengharuskan konversi ini memiliki perilaku yang tidak ditentukan.
Pertanyaannya kemudian adalah apakah suatu objek yang merupakan anggota serikat tidak aktif diinisialisasi dengan penyimpanan ke anggota serikat aktif. Sejauh yang saya tahu, ini tidak terjadi dan meskipun jika:
- serikat disalin ke dalam
char
penyimpanan array dan kembali (3.9: 2), atau
- sebuah serikat secara bersamaan disalin ke serikat lain dengan tipe yang sama (3.9: 3), atau
- sebuah serikat diakses melintasi batas-batas bahasa oleh elemen program yang sesuai dengan ISO / IEC 9899 (sejauh yang didefinisikan) (3.9: 4 catatan 42), kemudian
akses ke persatuan oleh anggota tidak aktif didefinisikan dan didefinisikan untuk mengikuti representasi objek dan nilai, akses tanpa salah satu dari interposisi di atas adalah perilaku yang tidak terdefinisi. Ini memiliki implikasi untuk optimisasi yang diperbolehkan untuk dilakukan pada program seperti itu, karena implementasi tentu saja dapat mengasumsikan bahwa perilaku yang tidak terdefinisi tidak terjadi.
Yaitu, meskipun kita dapat secara sah membentuk nilai untuk anggota serikat yang tidak aktif (itulah sebabnya menugaskan anggota yang tidak aktif tanpa konstruksi boleh saja) itu dianggap tidak diinisialisasi.