Pada hari-hari awal C ++ ketika dibaut di atas C, Anda tidak bisa menggunakan NULL seperti yang didefinisikan (void*)0
. Anda tidak dapat menetapkan NULL ke penunjuk selain void*
, yang membuatnya tidak berguna. Kembali pada masa itu, diterima bahwa Anda menggunakan 0
(nol) untuk pointer nol.
Sampai hari ini, saya terus menggunakan nol sebagai pointer nol tetapi orang-orang di sekitar saya bersikeras menggunakan NULL
. Saya pribadi tidak melihat manfaat apa pun untuk memberi nama ( NULL
) ke nilai yang ada - dan karena saya juga suka menguji pointer sebagai nilai kebenaran:
if (p && !q)
do_something();
kemudian menggunakan nol lebih masuk akal (seperti jika Anda menggunakan NULL
, Anda tidak dapat menggunakan secara logis p && !q
- Anda perlu membandingkan secara eksplisit NULL
, kecuali Anda menganggap NULL
nol, dalam hal ini mengapa digunakan NULL
).
Apakah ada alasan obyektif untuk memilih nol daripada NULL (atau sebaliknya), atau semua hanya preferensi pribadi?
Sunting: Saya harus menambahkan (dan seharusnya mengatakan) bahwa dengan RAII dan pengecualian, saya jarang menggunakan pointer nol / NULL, tetapi kadang-kadang Anda masih membutuhkannya.
Jawaban:
Inilah pendapat Stroustrup tentang ini: FAQ C ++ Style and Technique
Yang mengatakan, jangan keringat hal-hal kecil.
sumber
Ada beberapa argumen (salah satunya relatif baru) yang saya percaya bertentangan dengan posisi Bjarne dalam hal ini.
Menggunakan
NULL
memungkinkan untuk pencarian pada penggunaannya dan itu juga menyoroti bahwa pengembang ingin menggunakanNULL
pointer, terlepas dari apakah itu ditafsirkan oleh kompiler sebagaiNULL
atau tidak.Contoh yang dikutip semua orang adalah:
Namun, setidaknya menurut saya, masalah dengan hal di atas bukan karena kita menggunakan NULL untuk konstanta penunjuk nol, melainkan karena kita memiliki kelebihan 'foo' yang mengambil jenis argumen yang sangat berbeda. Parameter harus berupa
int
terlalu, karena jenis lain akan menghasilkan panggilan ambigu dan menghasilkan peringatan kompiler yang bermanfaat.Bahkan dengan tidak adanya C ++ 0x, ada alat yang tersedia saat ini yang memverifikasi yang
NULL
digunakan untuk pointer, dan yang0
digunakan untuk tipe integral.std::nullptr_t
tipe baru .Ini adalah argumen terbaru ke tabel. Masalah
0
danNULL
sedang ditangani secara aktif untuk C ++ 0x, dan Anda dapat menjamin bahwa untuk setiap implementasi yang menyediakanNULL
, hal pertama yang akan mereka lakukan adalah:Bagi mereka yang menggunakan
NULL
bukan0
, perubahan akan menjadi perbaikan dalam jenis-keselamatan dengan sedikit usaha atau tidak - jika sesuatu itu mungkin juga menangkap beberapa bug di mana mereka telah menggunakanNULL
untuk0
. Bagi siapa pun yang menggunakan0
hari ini .... erm ... semoga mereka memiliki pengetahuan yang baik tentang ekspresi reguler ...sumber
#include
dan tetap di sisi aman sepanjang jalan.#define NULL nullptr
tampaknya berbahaya. Untuk lebih baik atau lebih buruk, banyak kode lawas menggunakan NULL untuk hal-hal selain 0. Misalnya, pegangan sering diimplementasikan sebagai beberapa tipe integral, dan pengaturannya menjadiNULL
tidak biasa. Saya bahkan telah melihat pelanggaran seperti menggunakanNULL
untuk mengaturchar
terminator nol.NULL
itu sebenarnya salah. Banyak API telah lama digunakanNULL
dengan pegangan, dan itu sebenarnya penggunaan yang didokumentasikan dengan banyak dari mereka. Bukanlah pragmatis untuk tiba-tiba melanggarnya dan menyatakan bahwa mereka melakukan kesalahan.Gunakan NULL. NULL menunjukkan niat Anda. Itu 0 adalah detail implementasi yang seharusnya tidak masalah.
sumber
Saya selalu menggunakan:
NULL
untuk pointer'\0'
untuk karakter0.0
untuk mengapung dan gandadi mana 0 akan baik-baik saja. Ini masalah niat pensinyalan. Yang mengatakan, saya tidak anal tentang itu.
sumber
Saya berhenti menggunakan NULL yang mendukung 0 dulu (dan juga sebagian besar makro lainnya). Saya melakukan ini bukan hanya karena saya ingin menghindari macro sebanyak mungkin, tetapi juga karena NULL tampaknya telah menjadi terlalu banyak digunakan dalam kode C dan C ++. Tampaknya digunakan setiap kali nilai 0 diperlukan, bukan hanya untuk pointer.
Pada proyek-proyek baru, saya menempatkan ini di header proyek:
Sekarang, ketika compiler C ++ 0x compliant tiba, yang harus saya lakukan adalah menghapus baris itu. Manfaat yang bagus dari ini adalah bahwa Visual Studio sudah mengakui nullptr sebagai kata kunci dan menyorotnya dengan tepat.
sumber
Moral cerita. Anda harus menggunakan NULL ketika Anda berurusan dengan pointer.
1) Ini menyatakan maksud Anda (jangan buat saya mencari-cari semua kode Anda mencoba mencari tahu apakah variabel adalah pointer atau jenis numerik).
2) Dalam panggilan API tertentu yang mengharapkan argumen variabel, mereka akan menggunakan NULL-pointer untuk menunjukkan akhir dari daftar argumen. Dalam hal ini, menggunakan '0' bukannya NULL dapat menyebabkan masalah. Pada platform 64-bit, panggilan va_arg menginginkan pointer 64-bit, namun Anda hanya akan melewatkan integer 32-bit. Menurut saya Anda mengandalkan 32-bit lainnya untuk di-zero-out untuk Anda? Saya telah melihat kompiler tertentu (mis. ICPC Intel) yang tidak begitu ramah - dan ini menghasilkan kesalahan runtime.
sumber
NULL
mungkin tidak portabel, dan tidak aman. Mungkin ada platform yang masih#define NULL 0
(menurut FAQ Stroustrup: Haruskah saya menggunakan NULL atau 0? Dikutip oleh pertanyaan paling atas dan ini merupakan salah satu hasil pencarian pertama). Setidaknya dalam C ++ yang lebih lama,0
memiliki makna konseptual khusus dalam konteks pointer. Anda seharusnya tidak berpikir secara konkret tentang bit. Juga mencatat bahwa dalam konteks bilangan bulat yang berbeda (short
,int
,long long
) "sizeof(0)
" akan berbeda. Saya pikir jawaban ini agak salah kaprah.NULL
alih-alih(char *)0
,(const char *)0
atau(struct Boo *)0
atau(void *)0
atau apa pun untuk mengekspresikan maksud lebih jelas - tanpa (menurut saya) terlalu rumit.)Jika saya ingat dengan benar, NULL didefinisikan secara berbeda dalam header yang telah saya gunakan. Untuk C didefinisikan sebagai (void *) 0, dan untuk C ++ itu didefinisikan sebagai hanya 0. Kode terlihat seperti:
Secara pribadi saya masih menggunakan nilai NULL untuk mewakili pointer nol, itu membuatnya eksplisit bahwa Anda menggunakan pointer daripada beberapa tipe integral. Ya secara internal nilai NULL masih 0 tetapi tidak diwakili seperti itu.
Selain itu saya tidak bergantung pada konversi bilangan bulat ke nilai boolean secara otomatis tetapi secara eksplisit membandingkannya.
Misalnya lebih suka menggunakan:
daripada:
Cukuplah untuk mengatakan bahwa ini semua diatasi dalam C ++ 11 di mana seseorang dapat menggunakan
nullptr
alih-alihNULL
, dan juganullptr_t
itu adalah tipe anullptr
.sumber
Saya akan mengatakan sejarah telah berbicara dan mereka yang berpendapat mendukung 0 (nol) salah (termasuk Bjarne Stroustrup). Argumen yang mendukung 0 sebagian besar adalah estetika dan "preferensi pribadi".
Setelah pembuatan C ++ 11, dengan tipe nullptr baru, beberapa kompiler mulai mengeluh (dengan parameter default) tentang meneruskan 0 ke fungsi dengan argumen pointer, karena 0 bukan pointer.
Jika kode telah ditulis menggunakan NULL, pencarian dan penggantian sederhana dapat dilakukan melalui basis kode untuk menjadikannya nullptr. Jika Anda terjebak dengan kode yang ditulis menggunakan pilihan 0 sebagai pointer itu jauh lebih membosankan untuk memperbaruinya.
Dan jika Anda harus menulis kode baru sekarang ke standar C ++ 03 (dan tidak dapat menggunakan nullptr), Anda harus menggunakan NULL. Ini akan membuat Anda lebih mudah memperbarui di masa depan.
sumber
Saya biasanya menggunakan 0. Saya tidak suka makro, dan tidak ada jaminan bahwa beberapa header pihak ketiga yang Anda gunakan tidak mendefinisikan kembali NULL menjadi sesuatu yang aneh.
Anda bisa menggunakan objek nullptr seperti yang diusulkan oleh Scott Meyers dan lainnya hingga C ++ mendapatkan kata kunci nullptr:
Google "nullptr" untuk info lebih lanjut.
sumber
(void*)0
jika dikompilasi sebagai kode C) hanya meminta masalah dan tidak boleh digunakan.NULL
kelebihan(type *)0
adalah ketelusuran, menurut saya. Kalau tidak, tampaknya kebingungan yang tidak perlu jika itu bukan idiom C. Saya pribadi berpikir idiom penyebaranNULL
di semua tempat pantas mati.NULL
makro tidak berguna menurut saya. Pisau cukur Occam punya beberapa pekerjaan yang harus dilakukan di sini ...Saya pernah bekerja pada mesin di mana 0 adalah alamat yang valid dan NULL didefinisikan sebagai nilai oktal khusus. Pada mesin itu (0! = NULL), maka kode seperti
tidak akan berfungsi seperti yang Anda harapkan. Anda HARUS menulis
Walaupun saya percaya kebanyakan kompiler mendefinisikan NULL sebagai 0 hari ini saya masih ingat pelajaran dari tahun-tahun yang lalu: NULL belum tentu 0.
sumber
Saya pikir jaminan standar bahwa NULL == 0, sehingga Anda dapat melakukan keduanya. Saya lebih suka NULL karena ini mendokumentasikan maksud Anda.
sumber
foo.bar_ptr = (Bar *) 0
mengekspresikan maksud lebih jelas daripadafoo.bar_ptr = NULL
. Kebiasaan ini juga memberdayakan kompiler untuk menangkap kesalahan konsepsi untuk Anda. Bagi saya,foo.bar_ptr = 0
ungkapkan maksudnya juga menggunakanNULL
jika saya tahu itufoo.bar_ptr
adalah pointer.Menggunakan 0 atau NULL akan memiliki efek yang sama.
Namun, itu tidak berarti bahwa keduanya merupakan praktik pemrograman yang baik. Mengingat bahwa tidak ada perbedaan dalam kinerja, memilih opsi tingkat rendah sadar atas alternatif agnostik / abstrak adalah praktik pemrograman yang buruk. Bantu pembaca kode Anda memahami proses pemikiran Anda .
NULL, 0, 0.0, '\ 0', 0x00 dan semuanya menerjemahkan ke hal yang sama, tetapi merupakan entitas logis yang berbeda dalam program Anda. Mereka harus digunakan seperti itu. NULL adalah sebuah pointer, 0 adalah kuantitas, 0x0 adalah nilai yang bit-bitnya menarik, dll. Anda tidak akan menetapkan '\ 0' ke sebuah pointer apakah itu dikompilasi atau tidak.
Saya tahu beberapa komunitas mendorong untuk menunjukkan pengetahuan mendalam tentang suatu lingkungan dengan melanggar kontrak lingkungan. Namun, pemrogram yang bertanggung jawab membuat kode yang dapat dikelola dan menjaga praktik seperti itu dari kode mereka.
sumber
Aneh, tidak ada, termasuk Stroustroup menyebutkan itu. Sementara berbicara banyak tentang standar dan estetika tidak ada yang menyadari bahwa itu adalah berbahaya untuk digunakan
0
diNULL
's manfaat, misalnya, dalam daftar argumen variabel pada arsitektur manasizeof(int) != sizeof(void*)
. Seperti Stroustroup, saya lebih suka0
untuk alasan estetika, tetapi orang harus berhati-hati untuk tidak menggunakannya di mana tipenya mungkin ambigu.sumber
0
asalkan Anda menentukan0
Anda maksud - misalnya(int *)0
,(char *)0
,(const char *)0
atau(void *)0
atau(unsigned long long) 0
atau apa pun. Ini menurut pendapat saya mengungkapkan maksud lebih jelas daripadaNULL
.NULL
artinya.(void *)
ketika saya bisa menggunakan tipe yang tepat. Saya sengaja memberi contoh integer 64-bit (biasanya) dalam daftar karena analog dengan case pointer. Lebih jauh, jika ingatan saya bahwa C ++ lama didefinisikanNULL
sebagai0
akurat (sudah bertahun-tahun sejak saya diprogram dalam C ++), maka kami menyaksikan tidak ada peningkatan dalam kebenaran program. Standar C ++ yang lebih baru untungnya memberikannullptr
kata kunci, sehingga kita dapat menghilangkanNULL
kejelekan ini dan seluruh kontroversi saat menulis C ++ yang lebih baru.(void*)
telah diabstraksikanNULL
. DanNULL
sebenarnya mengekspresikan maksud cukup jelas sebagian besar waktu. Dan saya pikir ingatan Anda salah. Tidak yakin tentang standar, tetapi dalam praktiknya saya percaya sudah standar(void*)0
. Dan ya,nullptr
adalah prettifier yang bagus, meskipun jumlahnya samaNULL
saja - menentukan null-pointer tanpa menentukan tipe.nullptr
pesan yang samaNULL
, itu hanya tentang mengekspresikan maksud yang Anda sebutkan di awal. (MemprosesNULL
ulanggcc
hasil modern__null
, apa pun itu).Saya mencoba untuk menghindari seluruh pertanyaan dengan menggunakan referensi C ++ jika memungkinkan. Daripada
Anda mungkin sering dapat menulis
Tentu saja, ini tidak selalu berhasil; tetapi null pointer dapat digunakan secara berlebihan.
sumber
Saya menggunakan Stroustrup untuk yang ini :-) Karena NULL bukan bagian dari bahasa, saya lebih suka menggunakan 0.
sumber
Sebagian besar preferensi pribadi, meskipun orang dapat membuat argumen bahwa NULL membuatnya cukup jelas bahwa objek adalah pointer yang saat ini tidak mengarah ke apa pun, misalnya
IIRC, standar tidak memerlukan NULL menjadi 0, jadi menggunakan apa pun yang didefinisikan dalam <stddef.h> mungkin yang terbaik untuk kompiler Anda.
Sisi lain dari argumen ini adalah apakah Anda harus menggunakan perbandingan logis (pemeran implisit untuk bool) atau pemeriksaan explisit terhadap NULL, tetapi hal itu juga dapat dibaca.
sumber
Saya lebih suka menggunakan NULL karena menjelaskan bahwa maksud Anda adalah nilai yang mewakili pointer, bukan nilai aritmatika. Fakta bahwa itu adalah makro tidak menguntungkan, tetapi karena sudah berurat berakar banyak, hanya ada sedikit bahaya (kecuali seseorang melakukan sesuatu yang benar-benar bodoh). Saya berharap itu adalah kata kunci dari awal, tetapi apa yang dapat Anda lakukan?
Yang mengatakan, saya tidak punya masalah dengan menggunakan pointer sebagai nilai kebenaran dalam diri mereka sendiri. Seperti halnya NULL, ini adalah idiom yang mendarah daging.
C ++ 09 akan menambahkan konstruksi nullptr yang saya pikir sudah lama terlambat.
sumber
Saya selalu menggunakan 0. Bukan karena alasan yang dipikirkan, hanya karena ketika saya pertama kali belajar C ++ saya membaca sesuatu yang direkomendasikan menggunakan 0 dan saya selalu melakukannya dengan cara itu. Secara teori mungkin ada masalah kebingungan dalam keterbacaan tetapi dalam praktiknya saya belum pernah menemukan masalah seperti itu dalam ribuan jam kerja dan jutaan baris kode. Seperti yang dikatakan Stroustrup, itu benar-benar hanya masalah estetika pribadi sampai standarnya menjadi nullptr.
sumber
Seseorang pernah memberi tahu saya ... Saya akan mendefinisikan ulang NULL menjadi 69. Sejak itu saya tidak menggunakannya: P
Itu membuat kode Anda sangat rentan.
Edit:
Tidak semuanya dalam standar sempurna. Makro NULL adalah konstanta pointer tetapan C ++ null yang didefinisikan dengan implementasi tidak sepenuhnya kompatibel dengan makro C NULL, apa yang selain tipe menyembunyikan implisit mengubahnya dalam alat yang tidak berguna dan rentan terhadap kesalahan.
NULL tidak berperilaku sebagai pointer nol tetapi sebagai O / OL literal.
Katakan padaku contoh berikut ini tidak membingungkan:
Apakah karena semua itu, dalam standar baru muncul std :: nullptr_t
Jika Anda tidak ingin menunggu standar baru dan ingin menggunakan nullptr, gunakan setidaknya yang layak seperti yang diusulkan oleh Meyers (lihat komentar jon.h).
sumber
NULL
adalah bagian yang didefinisikan dengan baik dari standar C ++. Membiarkan orang yang suka mendefinisikan ulang makro standar mengedit kode dalam proyek Anda membuat kode Anda 'rentan'; menggunakanNULL
tidak.Yah saya berpendapat untuk tidak menggunakan 0 atau NULL pointer sama sekali bila memungkinkan.
Menggunakannya cepat atau lambat akan menyebabkan kesalahan segmentasi dalam kode Anda. Dalam pengalaman saya ini, dan pointer di gereral adalah salah satu sumber bug terbesar di C ++
juga, ini mengarah ke pernyataan "jika-tidak-nol" di seluruh kode Anda. Jauh lebih bagus jika Anda bisa mengandalkan selalu keadaan yang valid.
Hampir selalu ada alternatif yang lebih baik.
sumber
0
) adalah berguna untuk debugging. Jauh lebih baik daripada melakukan dereferencing sampah acak dan mendapatkan siapa yang tahu apa hasilnya.Mengatur pointer ke 0 tidak begitu jelas. Terutama jika Anda menggunakan bahasa selain C ++. Ini termasuk C serta Javascript.
Saya baru-baru delt dengan beberapa kode seperti:
virtual void DrawTo(BITMAP *buffer) =0;
untuk fungsi virtual murni untuk pertama kalinya. Saya pikir itu jiberjash ajaib selama seminggu. Ketika saya menyadari itu hanya pada dasarnya mengatur fungsi pointer ke
null
(karena fungsi virtual hanyalah fungsi pointer dalam kebanyakan kasus untuk C ++) saya menendang diri saya sendiri.virtual void DrawTo(BITMAP *buffer) =null;
akan kurang membingungkan daripada basterdation itu tanpa jarak yang tepat ke mata baru saya. Sebenarnya, saya bertanya-tanya mengapa C ++ tidak menggunakan huruf kecil
null
seperti mempekerjakan huruf kecil yang salah dan benar sekarang.sumber