Semua orang mengetahui Surat Dijkstra kepada editor: buka pernyataan yang dianggap berbahaya (juga di sini. Transkrip html dan di sini. Pdf) dan telah ada dorongan yang kuat sejak saat itu untuk menghindari pernyataan goto kapan pun memungkinkan. Meskipun dimungkinkan untuk menggunakan goto untuk menghasilkan kode yang luas dan tidak dapat dipelihara, namun tetap dalam bahasa pemrograman modern . Bahkan struktur kontrol lanjutan lanjutan dalam Skema dapat digambarkan sebagai goto canggih.
Keadaan apa yang menjamin penggunaan goto? Kapan sebaiknya menghindari?
Sebagai pertanyaan tindak lanjut: C menyediakan sepasang fungsi, setjmp dan longjmp, yang menyediakan kemampuan untuk pergi tidak hanya dalam frame stack saat ini tetapi dalam salah satu frame panggilan. Haruskah ini dianggap berbahaya seperti goto? Lebih berbahaya?
Dijkstra sendiri menyesalkan gelar itu, yang tidak bertanggung jawab padanya. Di akhir EWD1308 (juga di sini .pdf) ia menulis:
Akhirnya sebuah cerita pendek sebagai catatan. Pada tahun 1968, Komunikasi ACM menerbitkan teks tambang dengan judul " Pernyataan goto dianggap berbahaya ", yang pada tahun-tahun berikutnya akan paling sering dirujuk, namun sayangnya, sering oleh penulis yang tidak melihat lebih dari itu daripada yang judul, yang menjadi landasan ketenaran saya dengan menjadi templat: kita akan melihat semua jenis artikel dengan judul "X dianggap berbahaya" untuk hampir semua X, termasuk yang berjudul "Dijkstra dianggap berbahaya". Tetapi apa yang terjadi? Saya telah menyerahkan sebuah makalah dengan judul " Kasus yang menentang pernyataan kebohongan", yang, untuk mempercepat penerbitannya, editor telah berubah menjadi" surat kepada Editor ", dan dalam prosesnya ia memberinya judul baru dari penemuannya sendiri! Editornya adalah Niklaus Wirth.
Makalah klasik yang dipikirkan dengan baik tentang topik ini, untuk dicocokkan dengan Dijkstra, adalah Pemrograman Terstruktur dengan pergi ke Pernyataan , oleh Donald E. Knuth. Membaca keduanya membantu membangun kembali konteks dan pemahaman non-dogmatis tentang subjek. Dalam tulisan ini, pendapat Dijkstra tentang kasus ini dilaporkan dan bahkan lebih kuat:
Donald E. Knuth: Saya percaya bahwa dengan menyajikan pandangan seperti itu saya sebenarnya tidak setuju dengan ide-ide Dijkstra, karena dia baru-baru ini menulis yang berikut: "Tolong jangan jatuh ke dalam perangkap percaya bahwa saya sangat dogmatis tentang [the lanjut ke pernyataan]. Saya memiliki perasaan tidak nyaman bahwa orang lain membuat agama dari itu, seolah-olah masalah konseptual pemrograman dapat diselesaikan dengan satu trik, dengan bentuk disiplin kode yang sederhana! "
sumber
goto
.goto
: meretas alat pemrograman terstruktur bersama untuk mengimplementasikan agoto
.Jawaban:
Pernyataan berikut adalah generalisasi; Meskipun selalu memungkinkan untuk memohon pengecualian, biasanya (menurut pengalaman dan pendapat saya yang rendah hati) tidak sebanding dengan risikonya.
Catatan kaki di atas:
Mengenai poin 2, pertimbangkan kode berikut:
Pada titik "lakukan sesuatu" dalam kode, kita dapat menyatakan dengan keyakinan tinggi yang
a
lebih besar darib
. (Ya, saya mengabaikan kemungkinan bilangan bulat bilangan bulat yang tidak terbungkus. Mari kita tidak mengurangi contoh sederhana.)Di sisi lain, jika kode sudah dibaca dengan cara ini:
Banyaknya cara untuk mendapatkan label 10 berarti bahwa kita harus bekerja lebih keras untuk menjadi percaya diri tentang hubungan antara
a
danb
pada saat itu. (Faktanya, dalam kasus umum itu tidak dapat dipastikan!)Mengenai poin 4, seluruh gagasan "pergi ke suatu tempat" dalam kode hanyalah metafora. Tidak ada yang benar-benar "masuk" di mana saja di dalam CPU kecuali elektron dan foton (untuk panas yang terbuang). Terkadang kita memberikan metafora untuk yang lain, lebih bermanfaat, satu. Saya ingat menemukan (beberapa dekade yang lalu!) Bahasa di mana
diimplementasikan pada mesin virtual dengan mengkompilasi action-1 dan action-2 sebagai rutinitas tanpa parameter out-of-line, kemudian menggunakan opcode VM dua argumen tunggal yang menggunakan nilai boolean dari kondisi untuk memanggil satu atau yang lain. Konsepnya hanyalah "memilih apa yang akan dipanggil sekarang" daripada "pergi ke sini atau pergi ke sana". Sekali lagi, hanya perubahan metafora.
sumber
true
danfalse
dari jenis yang berbeda), dan setiap cabang dari if / else pada dasarnya adalah lambda.goto
dalam bahasa pemrograman modern (Go) stackoverflow.com/a/11065563/3309046 .Seorang rekan kerja saya mengatakan satu-satunya alasan untuk menggunakan GOTO adalah jika Anda memprogram diri sendiri sejauh ini ke sudut yang merupakan satu-satunya jalan keluar. Dengan kata lain, desain yang tepat sebelumnya dan Anda tidak perlu menggunakan GOTO nanti.
Saya pikir komik ini menggambarkan bahwa dengan indah, "Saya bisa merestrukturisasi aliran program, atau menggunakan sedikit 'GOTO' sebagai gantinya." GOTO adalah jalan keluar yang lemah ketika Anda memiliki desain yang lemah. Velociraptors memangsa yang lemah .
sumber
Terkadang valid untuk menggunakan GOTO sebagai alternatif untuk penanganan pengecualian dalam satu fungsi:
Kode COM tampaknya masuk ke dalam pola ini cukup sering.
sumber
Saya hanya ingat menggunakan goto sekali. Saya memiliki serangkaian lima loop terhitung bersarang dan saya harus dapat keluar dari seluruh struktur dari dalam awal berdasarkan kondisi tertentu:
Saya bisa saja dengan mudah mendeklarasikan variabel break boolean dan menggunakannya sebagai bagian dari kondisional untuk setiap loop, tetapi dalam hal ini saya memutuskan GOTO sama praktis dan mudah dibaca.
Tidak ada velociraptors yang menyerang saya.
sumber
goto
dan memberi kami pemrograman terstruktur juga menolak pengembalian awal, karena alasan yang sama. Turun ke seberapa mudah dibaca kode, seberapa jelas itu menyatakan maksud programmer. Membuat fungsi tanpa tujuan lain selain menghindari penggunaan kata kunci yang difitnah mengakibatkan kohesi yang buruk: penyembuhannya lebih buruk daripada penyakitnya.goto
, seseorang dapat secara eksplisit menentukan target. Denganbreak 5;
, (1) saya harus menghitung penutupan loop untuk menemukan tujuan; dan (2) jika struktur loop pernah berubah, mungkin perlu mengubah nomor itu agar tujuan tetap benar. Jika saya akan menghindarigoto
, maka keuntungannya adalah tidak harus melacak hal-hal seperti itu secara manual.Kami sudah melakukan diskusi ini dan saya mendukung pendapat saya .
Selain itu, saya muak dengan orang-orang yang menggambarkan struktur bahasa tingkat tinggi sebagai “
goto
menyamar” karena mereka jelas tidak mengerti maksudnya sama sekali . Sebagai contoh:Itu omong kosong. Setiap struktur kontrol dapat diimplementasikan dalam hal
goto
tetapi pengamatan ini benar-benar sepele dan tidak berguna.goto
tidak dianggap berbahaya karena efek positifnya tetapi karena konsekuensi negatifnya dan ini telah dieliminasi oleh pemrograman terstruktur.Demikian pula, mengatakan "GOTO adalah alat, dan karena semua alat, itu dapat digunakan dan disalahgunakan" benar-benar melenceng. Tidak ada pekerja bangunan modern yang akan menggunakan batu dan mengklaimnya "adalah alat." Batuan telah digantikan oleh palu.
goto
telah digantikan oleh struktur kontrol. Jika pekerja konstruksi terdampar di alam liar tanpa palu, tentu saja dia akan menggunakan batu. Jika seorang programmer harus menggunakan bahasa pemrograman inferior yang tidak memiliki fitur X, well, tentu saja ia mungkin harus menggunakannyagoto
. Tetapi jika dia menggunakannya di tempat lain alih-alih fitur bahasa yang sesuai, dia jelas tidak mengerti bahasa dengan benar dan menggunakannya dengan salah. Ini sangat sederhana.sumber
goto
. Anda benar sejauh saya tidak menawarkan argumen terhadap dirigoto
sendiri - saya tidak bermaksud - jadi tidak ada pertanyaan-mengemis.Goto sangat rendah dalam daftar hal untuk dimasukkan dalam program hanya demi itu. Itu tidak berarti itu tidak dapat diterima.
Goto bisa bagus untuk mesin negara. Pernyataan switch dalam satu loop adalah (dalam urutan kepentingan khas): (a) sebenarnya tidak mewakili aliran kontrol, (b) jelek, (c) berpotensi tidak efisien tergantung pada bahasa dan kompiler. Jadi Anda akhirnya menulis satu fungsi per negara, dan melakukan hal-hal seperti "kembalikan NEXT_STATE;" yang bahkan terlihat seperti goto.
Memang, sulit untuk kode mesin negara dengan cara yang membuatnya mudah dimengerti. Namun, tidak ada kesulitan yang berkaitan dengan penggunaan goto, dan tidak ada yang dapat dikurangi dengan menggunakan struktur kontrol alternatif. Kecuali jika bahasa Anda memiliki konstruksi 'mesin negara'. Milik saya tidak.
Pada saat-saat langka ketika algoritma Anda benar-benar paling mudah dipahami dalam hal jalur melalui urutan node (keadaan) yang dihubungkan oleh serangkaian transisi yang diizinkan (gotos), daripada oleh aliran kontrol yang lebih spesifik (loop, conditional, lainnya) ), maka itu harus eksplisit dalam kode. Dan Anda harus menggambar diagram yang cantik.
setjmp / longjmp bisa bagus untuk menerapkan pengecualian atau perilaku seperti pengecualian. Meskipun tidak dipuji secara universal, pengecualian umumnya dianggap sebagai struktur kontrol "valid".
setjmp / longjmp lebih 'berbahaya' daripada goto dalam arti bahwa mereka lebih sulit untuk digunakan dengan benar, apalagi pikiran komprehensif.
Mengambil goto dari C tidak akan membuatnya lebih mudah untuk menulis kode yang baik dalam C. Bahkan, lebih baik melewatkan titik bahwa C seharusnya mampu bertindak sebagai bahasa assembler yang dimuliakan.
Selanjutnya akan menjadi "pointer dianggap berbahaya", kemudian "mengetik bebek dianggap berbahaya". Lalu siapa yang akan ditinggalkan untuk membela Anda ketika mereka datang untuk mengambil konstruksi pemrograman Anda yang tidak aman? Eh?
sumber
Di Linux: Menggunakan goto Dalam Kode Kernel pada Kernel Trap, ada diskusi dengan Linus Torvalds dan "orang baru" tentang penggunaan GOTO dalam kode Linux. Ada beberapa poin yang sangat bagus di sana dan Linus mengenakan kesombongan seperti itu :)
Beberapa bagian:
-
-
sumber
goto cleanup_and_exit
adalah salah satu dari beberapa "baik" penggunaan goto tersisa sekarang bahwa kita memilikifor
,while
, danif
untuk mengelola aliran kendali kita. Lihat juga: programmers.stackexchange.com/a/154980Dalam C,
goto
hanya berfungsi dalam lingkup fungsi saat ini, yang cenderung melokalisasi bug potensial.setjmp
danlongjmp
jauh lebih berbahaya, bersifat non-lokal, rumit dan tergantung pada implementasi. Namun dalam praktiknya, mereka terlalu kabur dan jarang menyebabkan banyak masalah.Saya percaya bahwa bahaya
goto
di C sangat dibesar-besarkan. Ingatlah bahwagoto
argumen aslinya terjadi pada zaman bahasa seperti BASIC kuno, di mana pemula akan menulis kode spageti seperti ini:Di sini Linus menjelaskan penggunaan yang tepat dari
goto
: http://www.kernel.org/doc/Documentation/CodingStyle (bab 7).sumber
setjmp
/longjmp
hanya ditentukan ketika mereka digunakan sebagai cara melompat ke tempat dalam lingkup dari tempat lain dalam lingkup yang sama. Setelah kontrol meninggalkan ruang lingkup di manasetjmp
dieksekusi, setiap upaya untuk digunakanlongjmp
pada struktur yang dibuat olehsetjmp
akan menghasilkan perilaku yang tidak ditentukan.GOTO A * 40 + B * 200 + 30
. Tidak sulit untuk melihat bagaimana ini sangat berguna, dan sangat berbahaya.Hari ini, sulit untuk melihat masalah besar tentang
GOTO
pernyataan itu karena "pemrograman terstruktur" kebanyakan orang memenangkan perdebatan dan bahasa saat ini memiliki struktur aliran kontrol yang cukup untuk dihindariGOTO
.Hitung jumlah
goto
s dalam program C modern. Sekarang tambahkan jumlahbreak
,continue
danreturn
pernyataan. Selanjutnya, tambahkan berapa kali Anda menggunakanif
,else
,while
,switch
ataucase
. Itu tentang berapa banyakGOTO
program Anda akan memiliki jika Anda menulis dalam FORTRAN atau BASIC pada tahun 1968 ketika Dijkstra menulis suratnya.Bahasa pemrograman pada saat itu kurang dalam aliran kontrol. Misalnya, dalam BASIC Dartmouth asli:
IF
pernyataan tidakELSE
. Jika Anda menginginkannya, Anda harus menulis:Bahkan jika
IF
pernyataan Anda tidak memerlukanELSE
, itu masih terbatas pada satu baris, yang biasanya terdiri dari aGOTO
.Tidak ada
DO...LOOP
pernyataan. Untuk non-FOR
loop, Anda harus mengakhiri loop dengan eksplisitGOTO
atauIF...GOTO
kembali ke awal.Tidak ada
SELECT CASE
. Anda harus menggunakanON...GOTO
.Jadi, Anda berakhir dengan banyak dari
GOTO
dalam program Anda. Dan Anda tidak dapat bergantung pada pembatasanGOTO
s ke dalam satu subrutin tunggal (karenaGOSUB...RETURN
itu adalah konsep subrutin yang lemah), sehingga iniGOTO
bisa mana saja . Jelas, ini membuat aliran kontrol sulit untuk diikuti.Dari sinilah
GOTO
datangnya gerakan anti gerakan.sumber
420 if (rare_condition) then 3000
//430 and onward: rest of loop and other main-line code
//3000 [code for rare condition]
//3230 goto 430
. Menulis kode dengan cara seperti itu menghindari cabang yang diambil atau melompat dalam kasus garis utama umum, tetapi hal itu membuat hal-hal sulit untuk diikuti. Penghindaran cabang dalam kode rakitan bisa lebih buruk, jika beberapa cabang terbatas pada mis. +/- 128 byte dan kadang-kadang tidak memiliki pasangan pelengkap (mis. "Cjne" ada tetapi tidak "cje").cjne r0,expected_value,first_comp_springboard
/.../cjne r1,unexpected_value,second_comp_fallthrough
// `ajmp second_comp_target` //first_comp_springboard: ajmp first_comp_target
//second_comp_fallthrough: ...
. Bukan pola pengkodean yang sangat bagus, tetapi ketika siklus individu dihitung, seseorang melakukan hal-hal seperti itu. Tentu saja, pada tahun 1960-an, tingkat optimasi seperti itu lebih penting daripada hari ini, terutama karena CPU modern sering memerlukan optimasi aneh, dan sistem kompilasi just-in-time mungkin dapat menerapkan kode optimisasi untuk CPU yang tidak ada ketika kode yang dimaksud ditulis.Go To dapat menyediakan semacam stand-in untuk penanganan pengecualian "nyata" dalam kasus tertentu. Mempertimbangkan:
Jelas kode ini disederhanakan untuk mengambil lebih sedikit ruang, jadi jangan terlalu terpaku pada detail. Tetapi pertimbangkan alternatif yang saya lihat terlalu banyak dalam kode produksi oleh coders yang tidak masuk akal untuk menghindari penggunaan goto:
Sekarang secara fungsional kode ini melakukan hal yang sama persis. Bahkan, kode yang dihasilkan oleh kompiler hampir identik. Namun, dalam semangat programmer untuk menenangkan Nogoto (dewa teguran akademis yang ditakuti), programmer ini telah benar-benar melanggar idiom mendasar yang
while
diwakili oleh loop, dan melakukan bilangan real pada keterbacaan kode.Ini tidak lebih baik.Jadi, moral dari cerita ini adalah, jika Anda menemukan diri Anda menggunakan sesuatu yang benar-benar bodoh untuk menghindari penggunaan goto, maka jangan lakukan itu.
sumber
break
pernyataan itu berada di dalam struktur kontrol membuat jelas apa yang mereka lakukan. Dengangoto
contoh, orang yang membaca kode harus melihat kode untuk menemukan label, yang secara teori, sebenarnya bisa sebelum struktur kontrol. Saya tidak cukup berpengalaman dengan gaya lama C untuk membuat penilaian bahwa yang satu pasti lebih baik daripada yang lain, tetapi ada trade-off yang baik.break
s berada di dalam sebuah loop membuat jelas bahwa mereka keluar dari loop . Itu bukan "apa yang mereka lakukan", karena pada kenyataannya, tidak ada loop sama sekali! Tidak ada di dalamnya yang pernah memiliki kesempatan untuk mengulang, tetapi itu tidak jelas sampai akhir. Fakta bahwa Anda memiliki "lingkaran" yang tidak pernah berjalan lebih dari sekali, berarti bahwa struktur kontrol disalahgunakan. Dengangoto
contoh itu, programmer bisa mengatakangoto error_handler;
. Ini lebih eksplisit, dan bahkan lebih sulit untuk diikuti. (Ctrl + F, "error_handler:" untuk menemukan target. Coba lakukan itu dengan "}".)Donald E. Knuth menjawab pertanyaan ini dalam buku "Programate Literate", 1992 CSLI. Pada p. 17 ada esai " Pemrograman Terstruktur dengan Pernyataan goto " (PDF). Saya pikir artikel itu mungkin telah diterbitkan di buku-buku lain juga.
Artikel tersebut menggambarkan saran Dijkstra dan menjelaskan keadaan di mana ini berlaku. Tetapi dia juga memberikan sejumlah contoh counter (masalah dan algoritma) yang tidak dapat dengan mudah direproduksi menggunakan loop terstruktur saja.
Artikel ini berisi deskripsi lengkap tentang masalah, sejarah, contoh dan contoh balasan.
sumber
Goto dianggap membantu.
Saya mulai pemrograman pada tahun 1975. Bagi pemrogram era 1970-an, kata "goto dianggap berbahaya" kurang lebih mengatakan bahwa bahasa pemrograman baru dengan struktur kontrol modern layak untuk dicoba. Kami memang mencoba bahasa baru. Kami dengan cepat bertobat. Kami tidak pernah kembali.
Kami tidak pernah kembali, tetapi, jika Anda lebih muda, maka Anda tidak pernah ada di tempat pertama.
Sekarang, latar belakang dalam bahasa pemrograman kuno mungkin tidak terlalu berguna kecuali sebagai indikator usia programmer. Meskipun demikian, programmer yang lebih muda tidak memiliki latar belakang ini, sehingga mereka tidak lagi memahami pesan yang disampaikan slogan "goto dianggap berbahaya" kepada audiens yang dituju pada saat diperkenalkan.
Slogan-slogan yang tidak dimengerti tidak terlalu mencerahkan. Mungkin lebih baik melupakan slogan-slogan seperti itu. Slogan seperti itu tidak membantu.
Slogan khusus ini, "Goto dianggap berbahaya," telah mengambil nyawa mayat hidup sendiri.
Bisakah goto tidak disalahgunakan? Jawab: tentu, tapi terus kenapa? Praktis setiap elemen pemrograman dapat disalahgunakan. Yang rendah hati
bool
misalnya disalahgunakan lebih sering daripada yang ingin dipercaya oleh sebagian dari kita.Sebaliknya, saya tidak ingat pernah bertemu satu pun contoh penyalahgunaan goto sejak tahun 1990.
Masalah terbesar dengan goto mungkin bukan teknis tetapi sosial. Programmer yang tidak tahu banyak kadang-kadang tampaknya merasa bahwa kebosanan membuat mereka terdengar pintar. Anda mungkin harus memuaskan programmer seperti itu dari waktu ke waktu. Begitulah hidup.
Hal terburuk tentang goto hari ini adalah tidak cukup digunakan.
sumber
Tertarik oleh Jay Ballou menambahkan jawaban, saya akan menambahkan £ 0,02 saya. Jika Bruno Ranschaert belum melakukannya, saya akan menyebutkan artikel "Pemrograman Terstruktur dengan Pernyataan GOTO" Knuth.
Satu hal yang belum pernah saya lihat dibahas adalah jenis kode yang, meskipun tidak terlalu umum, diajarkan dalam buku teks Fortran. Hal-hal seperti rentang diperpanjang dari loop DO dan subrutin kode terbuka (ingat, ini akan menjadi Fortran II, atau Fortran IV, atau Fortran 66 - bukan Fortran 77 atau 90). Setidaknya ada kemungkinan detail sintaksisnya tidak eksak, tetapi konsepnya harus cukup akurat. Cuplikan di setiap kotak berada di dalam satu fungsi.
Perhatikan bahwa buku yang sangat bagus tetapi sudah usang (dan sudah tidak dicetak) ' The Elements of Programming Style, 2nd Edn ' oleh Kernighan & Plauger menyertakan beberapa contoh nyata penyalahgunaan GOTO dari buku-buku teks pemrograman pada masanya (akhir 70-an). Namun, materi di bawah ini bukan dari buku itu.
Kisaran yang diperluas untuk loop DO
Salah satu alasan untuk omong kosong seperti itu adalah kartu punch kuno yang bagus. Anda mungkin memperhatikan bahwa label (baik di luar urutan karena itu gaya kanonik!) Ada di kolom 1 (sebenarnya, mereka harus di kolom 1-5) dan kode ada di kolom 7-72 (kolom 6 adalah kelanjutan kolom penanda). Kolom 73-80 akan diberi nomor urut, dan ada mesin yang akan mengurutkan kartu punch menjadi urutan nomor urut. Jika Anda memiliki program Anda pada kartu berurutan dan perlu menambahkan beberapa kartu (garis) ke tengah-tengah loop, Anda harus mengulang semuanya setelah garis-garis ekstra. Namun, jika Anda mengganti satu kartu dengan barang GOTO, Anda dapat menghindari penyetelan kembali semua kartu - Anda hanya menyelipkan kartu baru di akhir rutin dengan nomor urut baru. Anggap itu sebagai upaya pertama 'komputasi hijau'
Oh, Anda mungkin juga mencatat bahwa saya curang dan tidak berteriak - Fortran IV ditulis dalam huruf besar semua secara normal.
Subrutin kode terbuka
GOTO antara label 76 dan 54 adalah versi goto yang dihitung. Jika variabel i memiliki nilai 1, kebagian label pertama dalam daftar (123); jika memiliki nilai 2, kebagian yang kedua, dan seterusnya. Fragmen dari 76 ke goto dihitung adalah subrutin kode terbuka. Itu adalah sepotong kode yang dieksekusi agak seperti subrutin, tetapi ditulis dalam tubuh fungsi. (Fortran juga memiliki fungsi pernyataan - yang merupakan fungsi tertanam yang dipasang pada satu baris.)
Ada konstruksi yang lebih buruk daripada goto yang dihitung - Anda bisa menetapkan label ke variabel dan kemudian menggunakan goto yang ditugaskan. Googling ditugaskan goto kepada memberi tahu saya itu dihapus dari Fortran 95. Kapur satu demi revolusi pemrograman terstruktur yang dapat dikatakan telah dimulai di depan umum dengan surat atau artikel "GOTO Considered Harmful" karya Dijkstra.
Tanpa pengetahuan tentang hal-hal yang dilakukan di Fortran (dan dalam bahasa lain, yang sebagian besar benar-benar jatuh di pinggir jalan), sulit bagi kita para pendatang baru untuk memahami ruang lingkup masalah yang ditangani oleh Dijkstra. Heck, saya tidak memulai pemrograman sampai sepuluh tahun setelah surat itu diterbitkan (tapi saya mengalami ketidakberuntungan untuk program di Fortran IV untuk sementara waktu).
sumber
goto
'in the wild', pertanyaan Dicari: Bekerja Algoritma Sortir Bose-Hibbard menunjukkan beberapa kode (Algol 60) yang diterbitkan pada tahun 1963. Tata letak aslinya tidak dibandingkan dengan standar pengkodean modern. Kode yang diklarifikasi (indentasi) masih cukup sulit dipahami. Thegoto
pernyataan ada lakukan membuatnya (sangat) sulit untuk memahami apa algoritma terserah.Tidak ada hal-hal seperti GOTO yang dianggap berbahaya .
GOTO adalah alat, dan karena semua alat, itu dapat digunakan dan disalahgunakan .
Namun, ada banyak alat di dunia pemrograman yang cenderung disalahgunakan lebih daripada digunakan , dan GOTO adalah salah satunya. yang DENGAN pernyataan Delphi adalah hal lain.
Secara pribadi saya tidak menggunakan salah satu dari kode yang umum , tetapi saya sudah memiliki penggunaan aneh GOTO dan WITH yang dibenarkan, dan solusi alternatif akan berisi lebih banyak kode.
Solusi terbaik adalah bagi kompiler untuk hanya memperingatkan Anda bahwa kata kunci itu ternoda , dan Anda harus memasukkan beberapa arahan pragma di sekitar pernyataan untuk menghilangkan peringatan.
Ini seperti memberi tahu anak-anak Anda untuk tidak lari dengan gunting . Gunting memang tidak buruk, tetapi beberapa penggunaannya mungkin bukan cara terbaik untuk menjaga kesehatan Anda.
sumber
goto
kata kunci dihapus dari C #, konsep "lompat di sini" masih ada di IL. Infinite loop dapat dengan mudah dibangun tanpa kata kunci goto. Jika tidak ada jaminan bahwa kode yang dipanggil akan kembali, menurut Anda, berarti "tidak dapat alasan tentang kode", maka saya akan mengatakan kami tidak pernah memiliki kemampuan itu.goto
dalam C # bukan "goto" nyata dalam arti asli dari kata tersebut. Ini adalah versi yang jauh lebih lemah yang hanya memungkinkan untuk melompat dalam suatu fungsi. Perasaan di mana saya menggunakan "goto" memungkinkan untuk melompat di mana saja dalam proses. Jadi, meskipun C # memiliki kata kunci "goto", kata itu bisa saja tidak pernah memiliki, goto nyata. Ya, goto nyata tersedia di tingkat IL, dengan cara yang sama ketika bahasa apa pun dikompilasi ke perakitan. Tetapi programmer terlindung dari itu, tidak dapat menggunakannya dalam keadaan normal, sehingga tidak masuk hitungan.Tidak pernah ada, selama Anda mampu berpikir untuk diri sendiri.
sumber
Sejak saya mulai melakukan beberapa hal di kernel linux, goto tidak terlalu mengganggu saya seperti dulu. Pada awalnya saya agak ngeri melihat mereka (kernel guys) menambahkan gotos ke dalam kode saya. Sejak itu saya menjadi terbiasa dengan penggunaan goto, dalam beberapa konteks terbatas, dan sekarang kadang-kadang akan menggunakannya sendiri. Biasanya, ini adalah kebalikan yang melompat ke akhir fungsi untuk melakukan semacam pembersihan dan bail out, daripada menduplikasi pembersihan dan bailout yang sama di beberapa tempat dalam fungsi. Dan biasanya, itu bukan sesuatu yang cukup besar untuk diserahkan ke fungsi lain - misalnya membebaskan beberapa variabel malloc'ed lokal adalah kasus khas.
Saya sudah menulis kode yang hanya menggunakan setjmp / longjmp. Itu dalam program sequencer drum MIDI. Putar ulang terjadi dalam proses terpisah dari semua interaksi pengguna, dan proses pemutaran menggunakan memori bersama dengan proses UI untuk mendapatkan info terbatas yang diperlukan untuk melakukan pemutaran. Ketika pengguna ingin menghentikan pemutaran, proses pemutaran hanya melakukan longjmp "kembali ke awal" untuk memulai dari awal, alih-alih beberapa pelonggaran rumit di mana pun itu akan dieksekusi ketika pengguna ingin berhenti. Itu bekerja dengan baik, sederhana, dan saya tidak pernah memiliki masalah atau bug yang terkait dengannya dalam hal itu.
setjmp / longjmp memiliki tempat mereka - tetapi tempat itu adalah salah satu yang Anda tidak akan mungkin mengunjungi tetapi sekali dalam waktu yang sangat lama.
Sunting: Saya baru saja melihat kode. Sebenarnya siglongjmp () yang saya gunakan, bukan longjmp (bukan itu masalah besar, tapi saya lupa bahwa siglongjmp bahkan ada.)
sumber
Jika Anda menulis VM di C, ternyata menggunakan goto yang dikomputasi (gcc) seperti ini:
bekerja jauh lebih cepat daripada saklar konvensional di dalam sebuah loop.
sumber
&&op_inc
tentu saja tidak mengkompilasi, karena (kiri)&
mengharapkan nilai, tetapi (kanan)&
menghasilkan nilai.Karena
goto
dapat digunakan untuk membingungkan metaprogrammingGoto
adalah ekspresi kontrol level tinggi dan level rendah , dan sebagai hasilnya ia tidak memiliki pola desain yang sesuai yang cocok untuk sebagian besar masalah.Ini tingkat rendah dalam arti bahwa goto adalah operasi primitif yang mengimplementasikan sesuatu yang lebih tinggi seperti
while
atauforeach
atau sesuatu.Ini tingkat tinggi dalam arti bahwa ketika digunakan dengan cara tertentu dibutuhkan kode yang mengeksekusi dalam urutan yang jelas, dengan cara yang tidak terputus, kecuali untuk loop terstruktur, dan mengubahnya menjadi potongan-potongan logika yang, dengan cukup
goto
s, ambil -tas logika sedang disusun kembali secara dinamis.Jadi, ada membosankan dan jahat sisi ke
goto
.Sisi prosa adalah bahwa goto menunjuk ke atas dapat menerapkan loop yang sangat masuk akal dan goto menunjuk ke bawah dapat melakukan hal yang masuk akal
break
ataureturn
. Tentu saja, yang aktualwhile
,,break
ataureturn
akan jauh lebih mudah dibaca, karena manusia miskin tidak perlu mensimulasikan efekgoto
untuk mendapatkan gambaran besar. Jadi, ide yang buruk secara umum.Sisi jahat melibatkan rutinitas tidak menggunakan goto untuk sementara, istirahat, atau kembali, tetapi menggunakannya untuk apa yang disebut logika spageti . Dalam hal ini pengembang goto-senang membangun potongan kode dari labirin goto, dan satu-satunya cara untuk memahaminya adalah dengan mensimulasikannya secara keseluruhan, tugas yang sangat melelahkan ketika ada banyak goto. Maksud saya, bayangkan kesulitan mengevaluasi kode di mana
else
tidak persis kebalikan dari ituif
, di mana bersarangif
mungkin memungkinkan dalam beberapa hal yang ditolak oleh luarif
, dll, dll.Akhirnya, untuk benar-benar membahas subjek, kita harus mencatat bahwa pada dasarnya semua bahasa awal kecuali Algol awalnya hanya membuat pernyataan tunggal yang tunduk pada versi mereka
if-then-else
. Jadi, satu-satunya cara untuk melakukan blok bersyarat adalahgoto
mengelilinginya menggunakan kondisional terbalik. Gila, saya tahu, tapi saya sudah membaca beberapa spesifikasi lama. Ingat bahwa komputer pertama diprogram dalam kode mesin biner jadi saya kira segala jenis HLL adalah penyelamat; Saya kira mereka tidak terlalu pilih-pilih tentang fitur HLL apa yang mereka dapatkan.Setelah mengatakan semua yang saya gunakan untuk memasukkan satu
goto
ke setiap program saya menulis "hanya untuk mengganggu para puritan" .sumber
Menolak penggunaan pernyataan GOTO kepada programmer seperti memberi tahu tukang kayu untuk tidak menggunakan palu karena dapat merusak dinding saat dia memalu paku. Seorang programmer sejati Mengetahui Bagaimana dan Kapan menggunakan GOTO. Saya telah mengikuti di belakang beberapa yang disebut 'Program Terstruktur' ini. Saya telah melihat kode Horrid hanya untuk menghindari penggunaan GOTO, sehingga saya bisa menembak programmer. Ok, untuk membela pihak lain, saya telah melihat beberapa kode spaghetti sungguhan juga, para programmer itu juga harus ditembak.
Ini hanya satu contoh kecil dari kode yang saya temukan.
-----------------------ATAU----------------------
sumber
goto
- dan tahu mengapa . Menghindari konstruksi bahasa yang tabu karena $ programming_guru mengatakan demikian, itulah definisi pemrograman pemujaan kargo."Di tautan ini http://kerneltrap.org/node/553/2131 "
Ironisnya, menghilangkan goto memperkenalkan bug: panggilan spinlock dihilangkan.
sumber
Makalah asli harus dianggap sebagai "GOTO Tanpa Syarat Dianggap Berbahaya". Itu khususnya menganjurkan bentuk pemrograman berdasarkan pada conditional (
if
) dan iterative (while
) constructs, daripada test-and-jump yang umum pada kode awal.goto
masih berguna dalam beberapa bahasa atau keadaan, di mana tidak ada struktur kontrol yang sesuai.sumber
Tentang satu-satunya tempat yang saya setujui Goto dapat digunakan adalah ketika Anda perlu menangani kesalahan, dan setiap titik tertentu kesalahan terjadi memerlukan penanganan khusus.
Misalnya, jika Anda mengambil sumber daya dan menggunakan semaphore atau mutex, Anda harus mengambilnya secara berurutan dan Anda harus selalu melepaskannya dengan cara yang berlawanan.
Beberapa kode memerlukan pola yang sangat aneh untuk mengambil sumber daya ini, dan Anda tidak bisa hanya menulis struktur kontrol yang mudah dipelihara dan dipahami untuk menangani dengan baik pengambilan dan pelepasan sumber daya ini untuk menghindari jalan buntu.
Selalu mungkin untuk melakukannya dengan benar tanpa kebohongan, tetapi dalam kasus ini dan beberapa lainnya, kebalikannya sebenarnya adalah solusi yang lebih baik terutama untuk keterbacaan dan pemeliharaan.
-Adam
sumber
Salah satu penggunaan GOTO modern adalah oleh kompiler C # untuk membuat mesin negara untuk enumerator yang ditentukan oleh pengembalian hasil.
GOTO adalah sesuatu yang harus digunakan oleh kompiler dan bukan programmer.
sumber
goto
. Di mana kita dapat menggunakangoto
mesin negara yang dikodekan dengan tangan untuk mengimplementasikan enumerator, kita bisa menggunakanyield
saja.Sampai C dan C ++ (di antara pelaku lainnya) telah memberi label istirahat dan berlanjut, goto akan terus memiliki peran.
sumber
Jika GOTO itu sendiri jahat, kompiler akan menjadi jahat, karena mereka menghasilkan JMP. Jika melompat ke blok kode, terutama mengikuti pointer, secara inheren jahat, instruksi RETurn akan menjadi jahat. Sebaliknya, kejahatan berpotensi untuk disalahgunakan.
Kadang-kadang saya harus menulis aplikasi yang harus melacak sejumlah objek di mana setiap objek harus mengikuti urutan rumit negara dalam menanggapi peristiwa, tetapi semuanya pasti single-thread. Urutan khas negara, jika direpresentasikan dalam pseudo-code adalah:
Saya yakin ini bukan hal baru, tetapi cara saya menanganinya dalam C (++) adalah mendefinisikan beberapa makro:
Kemudian (dengan asumsi awalnya 0) mesin state terstruktur di atas berubah menjadi kode terstruktur:
Dengan variasi pada ini, mungkin ada CALL dan RETURN, sehingga beberapa mesin negara dapat bertindak seperti subrutin mesin negara lainnya.
Apakah ini tidak biasa? Iya. Apakah perlu belajar dari pihak pengelola? Iya. Apakah pembelajaran itu membuahkan hasil? Aku pikir begitu. Bisakah itu dilakukan tanpa GOTO yang melompat ke blok? Nggak.
sumber
Saya menghindarinya karena rekan kerja / manajer pasti akan mempertanyakan penggunaannya baik dalam ulasan kode atau ketika mereka sengaja menemukannya. Meskipun saya pikir itu menggunakan (misalnya kasus penanganan kesalahan) - Anda akan bertabrakan dengan beberapa pengembang lain yang akan memiliki beberapa jenis masalah dengan itu.
Itu tidak layak.
sumber
Saya benar-benar menemukan diri saya terpaksa menggunakan goto, karena saya benar-benar tidak bisa memikirkan cara yang lebih baik (lebih cepat) untuk menulis kode ini:
Saya memiliki objek yang kompleks, dan saya perlu melakukan beberapa operasi padanya. Jika objek berada dalam satu keadaan, maka saya bisa melakukan versi cepat dari operasi, kalau tidak saya harus melakukan versi lambat dari operasi. Masalahnya adalah bahwa dalam beberapa kasus, di tengah operasi yang lambat, adalah mungkin untuk menyadari bahwa ini bisa dilakukan dengan operasi cepat.
Ini adalah bagian penting dari kode UI waktu nyata, jadi saya benar-benar berpikir bahwa GOTO dibenarkan di sini.
Hugo
sumber
Hampir semua situasi di mana goto dapat digunakan, Anda dapat melakukan hal yang sama menggunakan konstruksi lain. Lagipula Goto digunakan oleh kompiler.
Saya pribadi tidak pernah menggunakannya secara eksplisit, tidak perlu.
sumber
Satu hal yang saya tidak melihat dari salah satu jawaban di sini adalah bahwa solusi 'goto' sering lebih efisien dari satu solusi pemrograman terstruktur sering disebutkan.
Pertimbangkan kasus banyak-bersarang-loop, di mana menggunakan 'goto' bukan sekelompok
if(breakVariable)
bagian jelas lebih efisien. Solusi "Letakkan loop Anda dalam suatu fungsi dan gunakan kembali" seringkali sama sekali tidak masuk akal. Jika loop menggunakan variabel lokal, Anda sekarang harus melewati semuanya melalui parameter fungsi, berpotensi menangani banyak sakit kepala tambahan yang muncul dari itu.Sekarang perhatikan kasus pembersihan, yang sering saya gunakan sendiri, dan sangat umum sehingga diduga bertanggung jawab atas struktur coba {} catch {} tidak tersedia dalam banyak bahasa. Jumlah pemeriksaan dan variabel tambahan yang diperlukan untuk mencapai hal yang sama jauh lebih buruk daripada satu atau dua instruksi untuk melakukan lompatan, dan sekali lagi, solusi fungsi tambahan bukanlah solusi sama sekali. Anda tidak dapat memberi tahu saya bahwa itu lebih mudah dikelola atau lebih mudah dibaca.
Sekarang ruang kode, penggunaan tumpukan, dan waktu eksekusi mungkin tidak cukup berarti dalam banyak situasi bagi banyak programmer, tetapi ketika Anda berada di lingkungan yang tertanam dengan hanya 2KB ruang kode untuk bekerja, 50 byte instruksi tambahan untuk menghindari satu yang didefinisikan dengan jelas 'goto' hanya bisa ditertawakan, dan ini bukanlah situasi yang jarang seperti yang diyakini oleh banyak programmer tingkat tinggi.
Pernyataan bahwa 'goto berbahaya' sangat membantu dalam bergerak menuju pemrograman terstruktur, bahkan jika itu selalu merupakan generalisasi berlebihan. Pada titik ini, kita semua sudah cukup mendengarnya untuk berhati-hati menggunakannya (sebagaimana seharusnya). Ketika itu jelas alat yang tepat untuk pekerjaan itu, kita tidak perlu takut akan hal itu.
sumber
Anda dapat menggunakannya untuk memecah dari loop yang sangat bersarang, tetapi sebagian besar waktu kode Anda dapat di refactored menjadi lebih bersih tanpa loop yang terlalu dalam.
sumber