IMO, sono inclusi in Java e C # principalmente perché esistevano già in C ++. La vera domanda, quindi, è perché è C ++ in quel modo. Secondo The Design and Evolution of C ++ (§16.3):
La tryparola chiave è completamente ridondante, così come le { }parentesi, tranne nel caso in cui più istruzioni vengano effettivamente utilizzate in un blocco di prova o in un gestore. Ad esempio, sarebbe stato banale consentire:
int f()
{
return g() catch(xxii) { // not C++
error("G() goofed: xxii");
return 22;
};
}
Tuttavia, ho trovato così difficile spiegare che la ridondanza è stata introdotta per salvare il personale di supporto da utenti confusi.
Modifica: Per quanto riguarda il motivo per cui questo potrebbe essere fonte di confusione, penso che si debba solo guardare alle affermazioni errate nella risposta di @Tom Jeffery (e, soprattutto, il numero di voti positivi che ha ricevuto) per rendersi conto che ci sarebbe un problema. Per il parser, questo in realtà non è diverso dall'abbinare elses con ifs - mancano le parentesi graffe per forzare altri raggruppamenti, tutte le catch clausole corrisponderebbero al più recente throw. Per quelle lingue sbagliate che lo includono, le finallyclausole farebbero lo stesso. Dal punto di vista del parser, questo non è abbastanza diverso dalla situazione attuale da notare - in particolare, allo stato attuale delle grammatiche, non c'è davvero nulla per raggruppare le catchclausole - le parentesi raggruppano le dichiarazioni controllate dalcatch clausole, non le stesse clausole di cattura.
Dal punto di vista della scrittura di un parser, la differenza è quasi troppo piccola per essere notata. Se iniziamo con qualcosa del genere:
simple_statement: /* won't try to cover all of this */
;
statement: compound_statement
| simple_statement
;
statements:
| statements statement
;
compound_statement: '{' statements '}'
catch_arg: '(' argument ')'
Quindi la differenza sarebbe tra:
try_clause: 'try' statement
e:
try_clause: 'try' compound_statement
Allo stesso modo, per le clausole di cattura:
catch_clause: 'catch' catch_arg statement
vs.
catch_clause: 'catch' catch_arg compound_statement
Tuttavia, la definizione di un blocco try / catch completo non dovrebbe assolutamente cambiare. In entrambi i casi sarebbe qualcosa del tipo:
catch_clauses:
| catch_clauses catch_clause
;
try_block: try_clause catch_clauses [finally_clause]
;
[Qui sto usando [whatever]per indicare qualcosa di facoltativo, e sto tralasciando la sintassi per un finally_clausedato che non penso che abbia alcun rapporto con la domanda.]
Anche se non provi a seguire tutta la definizione grammaticale simile a Yacc lì, il punto può essere riassunto abbastanza facilmente: l'ultima affermazione (a partire da try_block) è quella in cui le catchclausole vengono abbinate alle tryclausole - e rimane esattamente il lo stesso sia che le parentesi graffe siano necessarie o meno.
Per ribadire / Riassumendo: il gruppo di parentesi graffe insieme delle dichiarazioni controllate dai le catchs, ma farlo senza gruppo il catchloro s. Come tale, quelle parentesi graffe non hanno assolutamente alcun effetto nel decidere quale catchva con quale try. Per il parser / compilatore l'attività è ugualmente facile (o difficile) in entrambi i casi. Nonostante questo, @ risposta di Tom (e il numero di up-voti è ricevuto) fornisce ampia dimostrazione del fatto che tale cambiamento una avrebbe utenti quasi certamente Confuse.
forle parti dovrebbe essere chiamato qualcosa di simileinitial,conditionesteppoichéinitialnon è necessario definire una variabile estepnon è necessario un incremento.