IMO, mereka termasuk dalam Java dan C # terutama karena mereka sudah ada di C ++. Pertanyaan sebenarnya adalah mengapa C ++ seperti itu. Menurut Desain dan Evolusi C ++ (§16.3):
Kata try
kunci benar-benar berlebihan dan begitu pula { }
tanda kurung kecuali di mana banyak pernyataan benar-benar digunakan dalam blok-coba atau penangan. Misalnya, sepele untuk mengizinkan:
int f()
{
return g() catch(xxii) { // not C++
error("G() goofed: xxii");
return 22;
};
}
Namun, saya menemukan ini sangat sulit untuk menjelaskan bahwa redundansi diperkenalkan untuk menyelamatkan personil pendukung dari pengguna yang bingung.
Sunting: Mengenai mengapa ini akan membingungkan, saya pikir kita hanya perlu melihat pernyataan yang salah dalam jawaban @Tom Jeffery (dan, terutama, jumlah suara yang diterima) untuk menyadari bahwa akan ada masalah. Bagi parser, ini benar-benar tidak berbeda dari mencocokkan else
dengan if
s - kurang kawat gigi untuk memaksa pengelompokan lain, semua catch
klausa akan cocok dengan yang terbaru throw
. Untuk bahasa-bahasa yang salah yang memasukkannya, finally
klausa akan melakukan hal yang sama. Dari sudut pandang parser, ini hampir tidak cukup berbeda dari situasi saat ini untuk diperhatikan - khususnya, karena tata bahasa berdiri sekarang, benar-benar tidak ada yang mengelompokkan catch
klausa bersama - kurung mengelompokkan pernyataan yang dikendalikan olehcatch
klausa, bukan tangkapan klausa sendiri.
Dari sudut pandang menulis parser, perbedaannya hampir terlalu kecil untuk diperhatikan. Jika kita mulai dengan sesuatu seperti ini:
simple_statement: /* won't try to cover all of this */
;
statement: compound_statement
| simple_statement
;
statements:
| statements statement
;
compound_statement: '{' statements '}'
catch_arg: '(' argument ')'
Maka perbedaannya adalah antara:
try_clause: 'try' statement
dan:
try_clause: 'try' compound_statement
Demikian juga, untuk klausa tangkap:
catch_clause: 'catch' catch_arg statement
vs.
catch_clause: 'catch' catch_arg compound_statement
Definisi blok coba / tangkap lengkap tidak perlu diubah sama sekali. Bagaimanapun itu akan menjadi seperti:
catch_clauses:
| catch_clauses catch_clause
;
try_block: try_clause catch_clauses [finally_clause]
;
[Di sini saya menggunakan [whatever]
untuk menunjukkan sesuatu yang opsional, dan saya meninggalkan sintaks untuk finally_clause
karena saya tidak berpikir ada kaitannya dengan pertanyaan.]
Bahkan jika Anda tidak mencoba mengikuti semua definisi tata bahasa seperti Yacc di sana, intinya dapat diringkas dengan cukup mudah: bahwa pernyataan terakhir (dimulai dengan try_block
) adalah pernyataan di mana catch
klausa dicocokkan dengan try
klausa - dan tetap persis seperti itu. sama apakah kawat gigi diperlukan atau tidak.
Untuk mengulangi / meringkas: kelompok kawat gigi bersama-sama laporan dikendalikan oleh para catch
s, tapi lakukan tidak kelompok catch
s sendiri. Dengan demikian, kawat gigi itu sama sekali tidak berpengaruh pada memutuskan mana catch
yang sesuai try
. Untuk parser / kompiler, tugasnya sama mudah (atau sulit). Meskipun demikian, jawaban @ Tom (dan jumlah suara yang diterima) memberikan banyak bukti bahwa perubahan semacam itu hampir pasti akan membingungkan pengguna.
for
bagian-bagian harus diberi nama sepertiinitial
,condition
danstep
karenainitial
tidak perlu mendefinisikan variabel danstep
tidak perlu kenaikan.