Messieurs, ils sont inclus dans Java et C # principalement parce qu’ils existaient déjà en C ++. La vraie question est donc de savoir pourquoi C ++ est ainsi. Selon la conception et l'évolution de C ++ (§16.3):
Le try
mot clé est complètement redondant, de même que les { }
crochets, sauf lorsque plusieurs instructions sont réellement utilisées dans un bloc try ou un gestionnaire. Par exemple, il aurait été trivial de permettre:
int f()
{
return g() catch(xxii) { // not C++
error("G() goofed: xxii");
return 22;
};
}
Cependant, j'ai trouvé cela tellement difficile à expliquer que la redondance avait été introduite pour éviter que le personnel de support ne soit confus.
Edit: Quant à savoir pourquoi cela serait source de confusion, je pense qu'il suffit de regarder les affirmations incorrectes contenues dans la réponse de Tom Tom Jeffery (et, en particulier, le nombre de votes positifs qu'il a reçus) pour se rendre compte qu'il y aurait un problème. Pour l'analyseur, cela ne diffère vraiment pas de l'appariement de else
s avec des if
accolades s manquantes pour forcer un autre groupe, toutes les catch
clauses correspondraient aux plus récentes throw
. Les clauses qui en font partie comprennent les finally
clauses mal faites. Du point de vue de l'analyseur, ceci est à peine assez différent de la situation actuelle pour s'en rendre compte - en particulier, à l'heure actuelle, les grammaires ne permettent pas de regrouper les catch
clauses - les crochets regroupent les instructions contrôlées par lecatch
clauses, pas les clauses de capture eux-mêmes.
Du point de vue de l'écriture d'un analyseur syntaxique, la différence est presque trop minime pour être remarquée. Si nous commençons avec quelque chose comme ceci:
simple_statement: /* won't try to cover all of this */
;
statement: compound_statement
| simple_statement
;
statements:
| statements statement
;
compound_statement: '{' statements '}'
catch_arg: '(' argument ')'
Alors la différence serait entre:
try_clause: 'try' statement
et:
try_clause: 'try' compound_statement
De même, pour les clauses de capture:
catch_clause: 'catch' catch_arg statement
contre.
catch_clause: 'catch' catch_arg compound_statement
Cependant, la définition d'un bloc try / catch complet n'aurait pas besoin de changer du tout. De toute façon, ce serait quelque chose comme:
catch_clauses:
| catch_clauses catch_clause
;
try_block: try_clause catch_clauses [finally_clause]
;
[Ici, j'utilise [whatever]
pour indiquer quelque chose d’optionnel, et je laisse de côté la syntaxe pour un finally_clause
puisque je ne pense pas que cela ait une incidence sur la question.]
Même si vous n'essayez pas de suivre toute la définition de la grammaire, à la manière de Yacc, le point peut être résumé assez facilement: cette dernière instruction (commençant par try_block
) est celle où les catch
clauses sont mises en correspondance avec des try
clauses - et cela reste exactement la même chose. même si les accolades sont nécessaires ou non.
Pour répéter / résumer: les accolades regroupent les instructions contrôlées par le catch
s, mais ne les regroupent pascatch
elles-mêmes. En tant que tels, ces accolades n’ont absolument aucun effet sur le choix du catch
choix try
. Pour l'analyseur / compilateur, la tâche est également facile (ou difficile) dans les deux cas. Malgré cela, la réponse @ Tom (et le nombre de votes up-il a reçu) fournit la démonstration suffisante du fait que le changement d' un tel feriez utilisateurs presque certainement embrouiller.
for
les parties doit être nommé quelque chose commeinitial
,condition
etstep
commeinitial
nécessité de ne pas définir une variable etstep
ne doit pas être une augmentation.