Perhatikan kode C ++ berikut:
void* a = &a;
Mengapa kompilator tidak mengeluh karena menggunakan pengenal yang tidak dideklarasikan?
Juga, apa yang dianggap oleh compiler sebagai variabel a
? Apakah ini penunjuk ke objek kosong atau penunjuk ke void*
penunjuk?
Jawaban:
Ruang lingkup deklarasi variabel di C ++ bisa sangat mengejutkan:
void* a = &a; ^~~~~~~~~~~~~~~~~ a declared as `void*` from here on
Oleh karena itu,
&a
adalahvoid**
tetapi karena jenis penunjuk apa pun secara implisit dapat diubah menjadivoid*
...sumber
a = &userfulObject
?void *a = a;
akan menjadi UB jika dideklarasikan secara lokal, jika tidak maka akan baik-baik saja pada cakupan namespace.Itu setara dengan
void* a; a = &a;
Oleh karena itu,
a
telah diumumkan. Jadia
dapatkan alamata
tertulis dalama
. Jadi ini adalah penunjuk ke penunjuk kosong. (Anda belum mendefinisikan objek apa pun.)sumber
a
itu sendiri adalah sebuah objek. (Tidak semua objek memiliki tipe yang ditentukan pengguna dalam C ++)In
void* a
,a
dideklarasikan sebagai pointer bukan kevoid
tipe tapi ke tipe "any" (kasus khusus). Sebuah alamat (posisi dalam memori) ditetapkan kea
, seperti variabel lain yang dideklarasikan, tentu saja.Setelah itu, ekspresi
&a
dievaluasi untuk menginisialisasi variabel (jugaa
, tapi ini tidak relevan) baru saja dideklarasikan. Jenisnya&a
adalah "penunjuk ke penunjuk ke jenis apa pun", yang merupakan kasus khusus "penunjuk ke jenis apa pun", sepenuhnya kompatibel dengan jenisa
. Ergo, tidak ada pesan penyusun.Akibat wajar: jangan gunakan
void*
jika Anda ingin pemeriksaan tipe yang kuat. Apa pun dapat diubah menjadi itu. Justru sebaliknya dalam arah sebaliknya, kecuali untukvoid*
dirinya sendiri (itu akan menjadi pengecualian yang tidak perlu bahwa suatu tipe tidak kompatibel dengan dirinya sendiri).Juga, AFAIR ini benar-benar berasal dari C.
sumber