Pertanyaan saya adalah tentang baris yang saya sebutkan dalam subjek dan yang dapat saya lihat di banyak tempat di dalam kode produksi.
Kode keseluruhan terlihat seperti ini:
if (0) {
// Empty braces
} else if (some_fn_call()) {
// actual code
} else if (some_other_fn_call()) {
// another actual code
...
} else {
// default case
}
Cabang-cabang lain tidak relevan dengan pertanyaan saya. Saya bertanya-tanya apa arti dari menempatkan di if (0)
sini. Kawat gigi itu kosong, jadi saya tidak berpikir itu seharusnya mengomentari beberapa blok kode. Apakah itu memaksa kompiler untuk membuat beberapa optimasi atau niatnya berbeda?
Saya telah mencoba mencari kasus eksplisit ini di sini di SO dan di internet, tetapi tidak berhasil. Ada pertanyaan serupa tentang JavaScript, tetapi tidak C. Ada pertanyaan lain, Apa yang terjadi ketika nol ditetapkan dalam kondisi `jika`? , tetapi membahas nol assignment ke variabel, bukan penggunaan 'if (0)' itu sendiri.
sumber
Jawaban:
Saya kadang-kadang menggunakan ini untuk simetri sehingga saya bisa bergerak
else if{
bebas dengan editor saya tanpa harus memikirkan yang pertamaif
.Secara semantik
bagian tidak melakukan apa-apa dan Anda dapat mengandalkan pengoptimal untuk menghapusnya.
sumber
if else
awalan umum untuk semua jalur kode signifikan melapisi kondisi dengan baik dan membuatnya lebih mudah untuk memindai. (Namun, itu subjektif, dan akan sangat tergantung pada apa yang sebenarnya ada di dalam kondisi dan blok kode.)if (0) {..}
memperkenalkan masalah keterbacaan / keterbacaan. Itu harus jelas bagi siapa saja yang tahu sedikit C. Itu bukan masalah. Masalahnya adalah pertanyaan lanjutan setelah membacanya: "Untuk apa itu?" Kecuali itu untuk keperluan debugging / sementara (yaitu, tujuannya adalah untuk "mengaktifkan"if
blok itu nanti), saya akan menyarankan untuk menghapus semuanya. Pada dasarnya "membaca" kode seperti itu kemungkinan akan menyebabkan "jeda" yang tidak perlu bagi pembaca tanpa alasan yang jelas. Dan itu alasan yang cukup bagus untuk menghapusnya.else if
sekitar editor tanpa khawatir" karena kondisinya mungkin tidak saling eksklusif, dalam hal urutan pesanan penting. Secara pribadi saya hanya akan menggunakanif
, dan melakukan pengembalian awal , mengekstraksi rantai logika ke fungsi terpisah jika perlu.Ini bisa bermanfaat jika ada
#if
pernyataan, aladll.
Dalam hal ini, semua (dan semua) tes dapat
#if
dihapus, dan kode akan dikompilasi dengan benar. Hampir semua kompiler akan menghapusif (0) {}
bagian tersebut. Autogenerator sederhana dapat menghasilkan kode seperti ini, karena sedikit lebih mudah untuk dikodekan - tidak harus mempertimbangkan blok pertama yang diaktifkan secara terpisah.sumber
if
/else if
tidak digunakan sebagai pohon keputusan, melainkan sebagai konstruksi "bertindak atas kondisi pencocokan pertama", di mana kondisi yang kebetulan memiliki prioritas tertinggi tidak terlalu "istimewa". Meskipun saya belum pernah melihatif(0)
digunakan sebagai cara untuk memungkinkan semua cabang nyata untuk memiliki sintaks yang konsisten, saya suka sintaks yang konsisten itu memfasilitasi.else if
garis menjadi dua dan menempatkan penjaga preprocessor di antaranya.if (0)
cabang dan memformat sisanya sehinggaelse
pada jalurnya sendiri, dikelilingi oleh penjaga sepanjang garis#if TEST1_ENABLED && TEST2_ENABLED
.Saya telah melihat pola serupa yang digunakan dalam kode yang dihasilkan. Sebagai contoh, dalam SQL, saya telah melihat perpustakaan mengeluarkan
where
klausa berikut .Hal ini mungkin membuatnya lebih mudah untuk hanya menambahkan kriteria lain, karena semua kriteria tambahan dapat ditambahkan dengan
and
bukannya memeriksa tambahan untuk melihat apakah itu adalah kriteria pertama atau tidak.sumber
1=1
juga "berguna" karena Anda selalu dapat menambahkanwhere
di depan, tanpa syarat. Kalau tidak, Anda harus memeriksa apakah itu kosong, dan jika demikian hindari menghasilkanwhere
klausa.1=1
dariWHERE
, sehingga tidak berdampak pada kinerja.Seperti yang tertulis,
if (0) {}
klausa tidak bisa dikompilasi.Saya menduga fungsi klausa di bagian atas tangga ini adalah untuk menyediakan tempat yang mudah untuk menonaktifkan sementara semua fungsi lainnya sekaligus (untuk tujuan debugging atau perbandingan) dengan mengubah
0
ke1
atautrue
.sumber
Saya tidak yakin dengan optimasi apa pun, tetapi dua sen saya:
Ini terjadi karena beberapa modifikasi kode, di mana satu kondisi utama telah dihapus, (fungsi memanggil di
if
blok awal , katakanlah), tetapi pengembang / pengelolaif-else
blokjadi alih-alih menghapus
if
blok terkait , mereka hanya mengubah kondisiif(0)
dan pindah.sumber
if(0)
mengurangi cakupan cabang juga?Ini membusuk kode.
Pada titik tertentu bahwa "jika" melakukan sesuatu yang bermanfaat, situasinya berubah, mungkin variabel yang dievaluasi dihapus.
Orang yang memperbaiki / mengubah sistem melakukan sesedikit mungkin untuk mempengaruhi logika sistem sehingga ia hanya memastikan kode akan dikompilasi ulang. Jadi dia meninggalkan "jika (0)" karena itu cepat dan mudah dan dia tidak sepenuhnya yakin itu yang ingin dia lakukan. Dia membuat sistem bekerja dan dia tidak kembali untuk memperbaikinya sepenuhnya.
Kemudian pengembang berikutnya datang dan berpikir bahwa itu dilakukan dengan sengaja dan hanya berkomentar bahwa bagian dari kode (karena itu tidak dievaluasi pula), maka pada saat kode disentuh komentar-komentar tersebut dihapus.
sumber
Satu kemungkinan belum disebutkan:
if (0) {
garis mungkin menyediakan tempat yang nyaman untuk breakpoint.Debugging sering dilakukan pada kode yang tidak dioptimalkan sehingga tes selalu-salah akan hadir dan dapat memiliki set breakpoint di atasnya. Ketika dikompilasi untuk produksi, garis kode akan dioptimalkan. Baris yang tampaknya tidak berguna memberikan fungsionalitas untuk pengembangan dan pengujian build tanpa memengaruhi build rilis.
Ada saran bagus lainnya di atas juga; satu-satunya cara untuk benar-benar tahu apa tujuannya, adalah melacak penulis dan bertanya. Sistem kontrol kode sumber Anda mungkin bisa membantu. (Cari
blame
fungsionalitas -type.)sumber
Saya telah melihat blok kode yang tidak dapat dijangkau dalam JavaScript yang diperluas yang telah dibuat menggunakan bahasa templating.
Misalnya, kode yang Anda baca bisa saja ditempelkan dari server yang pra-mengevaluasi kondisi pertama yang pada saat itu bergantung pada variabel yang hanya tersedia di sisi server.
yang pernah pra-disusun pagar:
Saya harap ini membantu Anda merelatifkan potensi aktivitas papan ketik rendah dari zaman coders pro-daur ulang yang membuat saya sangat antusias!
sumber
Konstruk itu juga dapat digunakan dalam C untuk mengimplementasikan pemrograman generik dengan tipe keselamatan, dengan mengandalkan pada fakta bahwa kode yang tidak terjangkau masih diperiksa oleh kompiler:
sumber
Saya pikir itu hanya kode yang buruk. Menulis contoh cepat di Compiler Explorer, kita melihat bahwa di gcc dan dentang tidak ada kode yang dihasilkan untuk
if (0)
blok, bahkan dengan optimasi sepenuhnya dinonaktifkan:https://godbolt.org/z/PETIks
Bermain-main dengan menghapus
if (0)
penyebab tidak ada perubahan pada kode yang dihasilkan, jadi saya menyimpulkan bahwa ini bukan optimasi.Mungkin saja ada sesuatu di
if
blok atas yang kemudian dihapus. Singkatnya, sepertinya menghapusnya akan menyebabkan kode yang sama persis dihasilkan, jadi jangan ragu untuk melakukannya.sumber
Seperti yang telah dikatakan, nol dievaluasi menjadi false, dan cabang kemungkinan akan dioptimalkan oleh kompiler.
Saya juga pernah melihat ini sebelumnya dalam kode di mana fitur baru ditambahkan dan kill-switch diperlukan (jika ada yang salah dengan fitur Anda hanya dapat mematikannya), dan beberapa waktu kemudian ketika kill-switch dihapus programmer juga tidak menghapus cabang, misalnya
menjadi
sumber
Ini membantu untuk men-debug blok ini hanya dengan meletakkan jika blok 1. Ini menonaktifkan semua fungsi blok jika lain Dan juga kita dapat memperluas blok if else.
sumber
sumber
@ Jawaban PSkocik baik-baik saja, tapi saya menambahkan dua sen saya. Tidak yakin apakah saya harus melakukan ini sebagai komentar, atau sebagai jawaban; memilih yang terakhir, karena IMHO layak dilihat orang lain, sedangkan komentar sering tidak terlihat.
Saya tidak hanya sesekali menggunakan
Tapi saya juga sesekali melakukannya
atau
untuk kondisi yang rumit. Untuk alasan yang sama - lebih mudah untuk diedit, #ifdef, dll.
Untuk itu, di Perl saya akan lakukan
Saya membandingkan
if(0)
kode dengan lispyang, Anda dapat menebaknya, saya mungkin indent sebagai
Saya kadang-kadang mencoba membayangkan seperti apa sintaksis yang bisa dibaca manusia untuk ini.
Mungkin
terinspirasi oleh Dikstra [ https://en.wikipedia.org/wiki/Guarded_Command_Language#Selection:_if[[Guarded Command Language].
Tetapi sintaks ini menyiratkan bahwa kondisi dievaluasi secara paralel, sedangkan
if...else-if
menyiratkan evaluasi kondisi berurutan dan diprioritaskan.Saya mulai melakukan hal semacam ini ketika menulis program yang menghasilkan program lain, di mana itu sangat nyaman.
Sementara kita berada di dalamnya, ketika menulis RTL menggunakan iHDL lama Intel, saya memiliki hal-hal seperti kode
di mana
FORC..DOC..ENDC
adalah konstruksi lingkaran preprocessor makro, yang diperluas keIni adalah penugasan tunggal, non-imperatif, kode, jadi menetapkan variabel keadaan tidak diizinkan, jika Anda perlu melakukan hal-hal seperti menemukan bit set pertama.
Kalau dipikir-pikir, ini mungkin adalah tempat pertama yang saya temui konstruksi seperti itu.
BTW, keberatan bahwa sebagian orang memiliki gaya if (0) - bahwa kondisi lain-jika-tergantung secara berurutan dan tidak dapat secara sewenang-wenang dipesan ulang - tidak berlaku untuk logika AND dan OR dan XOR dalam RTL - tetapi berlaku untuk short- sirkuit && dan ||.
sumber
Saya telah melihat ini digunakan untuk menangani kesalahan, misalnya
Ini bisa membantu ketika goto digunakan untuk mengelola kesalahan, pernyataan dieksekusi hanya ketika kesalahan terjadi. Saya melihat ini dalam kode C yang sangat lama (di mana argumen fungsi ditulis di luar '()'), jangan berpikir ada yang mengikuti ini sekarang.
sumber
Saya telah melihat ini beberapa kali, saya pikir alasan yang paling mungkin adalah ia mengevaluasi sesuatu dalam versi / cabang / kode yang berbeda, atau mungkin untuk debugging, dan mengubahnya menjadi
if(0)
cara yang agak malas untuk menghapus apa pun yang ada di sana .sumber