Mengapa bahasa tidak menggunakan fall-through eksplisit pada pernyataan switch?

17

Saya sedang membaca Mengapa kita harus menggunakan breakdi switch? , dan itu membuat saya bertanya-tanya mengapa fall-through implisit diizinkan dalam beberapa bahasa (seperti PHP dan JavaScript), sementara tidak ada dukungan (AFAIK) untuk fall-through eksplisit.

Ini tidak seperti kata kunci baru yang perlu dibuat, karena continueakan sangat tepat, dan akan menyelesaikan masalah ambiguitas untuk apakah penulis bermaksud untuk menyelesaikan kasus.

Formulir yang saat ini didukung adalah:

switch (s) {
    case 1:
        ...
        break;
    case 2:
        ... //ambiguous, was break forgotten?
    case 3:
        ...
        break;
    default:
        ...
        break;
}

Sedangkan akan masuk akal untuk ditulis sebagai:

switch (s) {
    case 1:
        ...
        break;
    case 2:
        ...
        continue; //unambiguous, the author was explicit
    case 3:
        ...
        break;
    default:
        ...
        break;
}

Untuk keperluan pertanyaan ini, mari kita abaikan masalah apakah fall-throughs adalah gaya pengkodean yang baik atau tidak.

Apakah ada bahasa yang ada yang memungkinkan fall-through dan membuatnya eksplisit?

Apakah ada alasan historis yang switchmemungkinkan kejatuhan tersirat alih-alih eksplisit?

zzzzBov
sumber
4
C # mengharuskan Anda untuk secara eksplisit goto case, sehingga alasan pertanyaan Anda agak salah.
pdr
1
@ pdr, saya secara eksplisit bertanya apakah ada bahasa yang sudah mendukung fall-through, saya tidak tahu goto casedi C #.
zzzzBov
Ya, maaf, saya merindukan ada dua bagian dari pertanyaan Anda. Sayangnya, jika diungkapkan, saya memilih untuk menutup karena sangat dekat dengan pertanyaan jajak pendapat. Akan ada banyak jawaban yang benar.
pdr
C # juga memungkinkan Anda untuk memiliki beberapa label yang berbagi daftar pernyataan yang sama, yang menghilangkan beberapa situasi yang mengharuskan jatuh. Selebihnya, demikian goto case, seperti disebutkan pdr.
Brian

Jawaban:

20

Ini terutama historis, sebagian besar bahasa hanya menyalin apa yang dilakukan C.

Alasan bahwa C melakukannya dengan cara itu adalah bahwa pencipta C berniat beralih pernyataan agar mudah dioptimalkan ke dalam tabel lompatan. Ini juga alasan bahwa C membatasi pernyataan beralih ke nilai integral.

Dalam tabel lompatan, program akan menghitung posisi apa yang harus dilompati berdasarkan ekspresi. Program akan melompat ke titik itu dan kemudian melanjutkan mengeksekusi dari titik itu. Jika Anda ingin melewati sisa tabel Anda harus memasukkan lompatan ke ujung tabel. C menggunakan breakpernyataan eksplisit sehingga ada korespondensi langsung dengan konstruk ini.

Dirk Holsopple
sumber
7
Sebagai catatan kecil, dalam bukunya "Expert C Programming", Peter van der Linden menyebutkan bahwa ketika ia bekerja untuk Sun pada C compiler mereka, beberapa ~ 97% dari kasus saklar yang terkandung breakdan hanya kurang dari 3% yang jatuh-melalui . Dia kemudian menggunakan ini sebagai contoh bahwa perilaku default fall-through adalah kontra-intuitif dan akan lebih baik jika dibalik (gunakan kata kunci untuk menunjukkan fall-through eksplisit). Oh, dan buku ini sangat bagus untuk menjelaskan keanehan C lainnya, beberapa di antaranya ditemukan di C ++ dan bahkan di C # dan Java juga! Semuanya berakar pada B dan BCPL. :)
zxcdw
3
Ada bahasa pemrograman di mana jatuh melalui eksplisit, seperti c # ( msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx ). Di sisi lain, melanggar juga eksplisit di c #.
linkerro
@zxcdw: Sayang sekali tidak mungkin birdy kecil bisa kembali ke masa lalu dan menyarankan bahwa label apa pun yang ditandai case, selain yang pertama, harus diawali secara otomatis break, tetapi yang bertanda +case(atau beberapa penanda lainnya) tidak boleh. Itu akan mudah bagi kompiler untuk menangani dan memungkinkan keuntungan semantik dari pengaturan ini, sambil menghilangkan banyak baris kode.
supercat
7

Go memungkinkan fallthrough eksplisit menggunakan fallthroughkata kunci (break implisit, tetapi mungkin eksplisit):

switch val {
case 1: // breaks
case 2:
    fallthrough
case 3:
    goto 
case 4, 5, 6: // equivalent to defining individual cases with explicit fallthough
    break // unnecessary
default:
}

Inilah bagian yang relevan dari langkah efektif dan spesifikasi bahasa .

Saya tidak berpikir Anda dapat menggunakan gotountuk pergi ke kasus tertentu, tetapi Anda dapat membuat label di dalam kasus ini dan menggunakan gotoseperti biasa.

Sebagai bonus, Go memungkinkan Anda menggunakan ekspresi biner, string, atau tipe dalam switch sebagai pernyataan kasus.

hajar
sumber