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 trykunci 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 elsedengan ifs - kurang kawat gigi untuk memaksa pengelompokan lain, semua catch klausa akan cocok dengan yang terbaru throw. Untuk bahasa-bahasa yang salah yang memasukkannya, finallyklausa 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 catchklausa 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_clausekarena 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 catchklausa dicocokkan dengan tryklausa - dan tetap persis seperti itu. sama apakah kawat gigi diperlukan atau tidak.
Untuk mengulangi / meringkas: kelompok kawat gigi bersama-sama laporan dikendalikan oleh para catchs, tapi lakukan tidak kelompok catchs sendiri. Dengan demikian, kawat gigi itu sama sekali tidak berpengaruh pada memutuskan mana catchyang 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.
forbagian-bagian harus diberi nama sepertiinitial,conditiondanstepkarenainitialtidak perlu mendefinisikan variabel dansteptidak perlu kenaikan.