Jawabannya tergantung pada sudut pandang Anda:
Jika Anda menilai dengan standar C ++, Anda tidak bisa mendapatkan referensi null karena Anda mendapatkan perilaku tidak terdefinisi terlebih dahulu. Setelah kejadian pertama dari perilaku tidak terdefinisi, standar memungkinkan segala sesuatu terjadi. Jadi, jika Anda menulis *(int*)0
, Anda sudah memiliki perilaku yang tidak terdefinisi seperti Anda, dari sudut pandang standar bahasa, mengabaikan pointer nol. Sisa program tidak relevan, setelah ungkapan ini dijalankan, Anda keluar dari permainan.
Namun, dalam praktiknya, referensi null dapat dengan mudah dibuat dari pointer null, dan Anda tidak akan menyadarinya sampai Anda benar-benar mencoba mengakses nilai di belakang referensi null. Contoh Anda mungkin agak terlalu sederhana, karena setiap kompiler pengoptimalan yang baik akan melihat perilaku tidak terdefinisi, dan hanya mengoptimalkan apa pun yang bergantung padanya (referensi nol bahkan tidak akan dibuat, itu akan dioptimalkan).
Namun, pengoptimalan tersebut bergantung pada compiler untuk membuktikan perilaku tidak terdefinisi, yang mungkin tidak dapat dilakukan. Pertimbangkan fungsi sederhana ini di dalam file converter.cpp
:
int& toReference(int* pointer) {
return *pointer;
}
Ketika kompilator melihat fungsi ini, ia tidak tahu apakah pointernya adalah pointer null atau bukan. Jadi itu hanya menghasilkan kode yang mengubah pointer apa pun menjadi referensi yang sesuai. (Btw: Ini adalah noop karena pointer dan referensi adalah binatang yang sama persis di assembler.) Sekarang, jika Anda memiliki file lain user.cpp
dengan kode
#include "converter.h"
void foo() {
int& nullRef = toReference(nullptr);
cout << nullRef; //crash happens here
}
kompilator tidak tahu bahwa toReference()
akan mendereferensi penunjuk yang diteruskan, dan menganggap bahwa ia mengembalikan referensi yang valid, yang dalam praktiknya akan menjadi referensi nol. Panggilan berhasil, tetapi ketika Anda mencoba menggunakan referensi, program lumpuh. Semoga. Standar tersebut memungkinkan terjadinya apa saja, termasuk penampilan gajah merah muda.
Anda mungkin bertanya mengapa ini relevan, lagipula, perilaku tidak terdefinisi sudah dipicu di dalam toReference()
. Jawabannya adalah debugging: Referensi nol dapat menyebar dan berkembang biak seperti yang dilakukan pointer nol. Jika Anda tidak menyadari bahwa referensi null bisa ada, dan belajar untuk menghindari pembuatannya, Anda mungkin meluangkan cukup waktu untuk mencoba mencari tahu mengapa fungsi anggota Anda tampaknya macet ketika hanya mencoba membaca anggota lama yang biasa int
(jawaban: contoh dalam panggilan anggota itu referensi nol, begitu this
juga pointer nol, dan anggota Anda dihitung untuk ditempatkan sebagai alamat 8).
Jadi bagaimana dengan memeriksa referensi null? Anda memberi garis
if( & nullReference == 0 ) // null reference
dalam pertanyaan Anda. Nah, itu tidak akan berhasil: Menurut standar, Anda memiliki perilaku yang tidak terdefinisi jika Anda mendereferensi penunjuk nol, dan Anda tidak dapat membuat referensi nol tanpa mendereferensi penunjuk null, jadi referensi null hanya ada di dalam ranah perilaku tidak terdefinisi. Karena kompilator Anda mungkin berasumsi bahwa Anda tidak memicu perilaku yang tidak ditentukan, ia dapat berasumsi bahwa tidak ada yang namanya referensi null (meskipun ia dengan mudah akan mengeluarkan kode yang menghasilkan referensi null!). Dengan demikian, ia melihat if()
kondisinya, menyimpulkan bahwa itu tidak mungkin benar, dan hanya membuang seluruh if()
pernyataan. Dengan diperkenalkannya pengoptimalan waktu tautan, menjadi sangat tidak mungkin untuk memeriksa referensi null dengan cara yang kuat.
TL; DR:
Referensi kosong agaknya merupakan keberadaan yang mengerikan:
Keberadaan mereka tampaknya tidak mungkin (= menurut standar),
tetapi mereka ada (= oleh kode mesin yang dihasilkan),
tetapi Anda tidak dapat melihatnya jika ada (= upaya Anda akan dioptimalkan),
tetapi mereka mungkin membunuh Anda tanpa menyadarinya (= program Anda macet di titik-titik aneh, atau lebih buruk lagi).
Satu-satunya harapan Anda adalah mereka tidak ada (= tulis program Anda untuk tidak membuatnya).
Saya berharap hal itu tidak akan menghantui Anda!