2013-08-27 5 views
7

Je viens de lire que dans la révision standard C++ 11, les spécifications d'exception étaient obsolètes. J'ai déjà pensé que spécifier ce que vos fonctions peuvent lancer est une bonne pratique, mais apparemment pas. Après avoir lu Herb Stutter's well-cited article, je ne peux m'empêcher de me demander: pourquoi diable les spécifications d'exception sont-elles implémentées comme elles sont et pourquoi le comité a-t-il décidé de les déprécier au lieu de les faire vérifier à la compilation? Pourquoi un compilateur autoriserait-il même une exception qui n'apparaîtrait pas dans la définition de la fonction? Pour moi, tout cela ressemble à dire "Vous ne devriez probablement pas spécifier le type de retour de votre fonction, car lorsque vous spécifiez int f(), mais return 3.5; à l'intérieur, votre programme va probablement planter." (C.-à-où est la conceptuelle différence de la forte frappe?)Pourquoi les spécifications d'exception C++ ne sont-elles pas vérifiées lors de la compilation?

(Pour le manque de soutien de la spécification d'exception dans typedef s, étant donné que la syntaxe du modèle est probablement Turing-complet, la mise en œuvre cela semble assez facile.)

+0

Une chose importante à noter est que les compilateurs ne peuvent pas toujours voir la définition. –

+0

Je pense qu'une grande raison est que cela casserait beaucoup de bon code de modèle. –

+0

(Et si vous voulez pousser plus loin, pourquoi un compilateur permettrait-il même à une fonction d'accéder à des variables qui n'apparaissent pas dans la déclaration de fonction?) –

Répondre

-1

Si la fonction f() throw(int) appelait la fonction g() throw(int, double), que se passerait-il? Une vérification du temps de compilation empêcherait votre fonction d'appeler n'importe quelle autre fonction avec un spécificateur de lancer moins strict, ce qui serait très pénible.

+1

si la fonction 'int f()' renvoyait le résultat de 'double g()' sans conversion, ne pas avoir cette augmentation une erreur ne serait pas une énorme douleur, mais, bien, une erreur. Et je n'ai rien dit de rendre obligatoire quelque chose; on pourrait toujours déclarer 'f()' sans spécificateur 'throw' ... – Taral

11

La raison initiale était qu'il a été jugé impossible de fiable chèque donné le corps du code existant, et le fait qu'aucun spécificateur signifie quelque chose peut jeter. Ce qui signifie que si vérification statique était en vigueur, le code suivant ne serait pas compilation:

double 
safeSquareRoot(double d) throw() 
{ 
    return d > 0.0 ? sqrt(d) : 0.0; 
} 

En outre, le but des exceptions doivent rapporter des erreurs sur une grande distance, ce qui signifie que les fonctions intermédiaires ne devrait pas savoir ce que les fonctions qu'ils appellent pourraient jeter. Exiger des spécificateurs d'exception sur ceux-ci romprait l'encapsulation .

Le seul cas réel où une fonction a besoin de savoir sur les exceptions qui pourraient se produire est de savoir quelles sont les exceptions ne peuvent pas se produire . En particulier, il est impossible d'écrire le code de fil de sécurité sauf si vous pouvez être assuré que certaines fonctions ne seront jamais . Même ici, la vérification statique n'est pas acceptable, pour les raisons expliquées ci-dessus, donc la spécification d'exception est conçu pour fonctionner plus comme une assertion que vous ne pouvez pas désactiver: lorsque vous écrivez throw(), vous obtenez plus ou moins l'équivalent de un échec d'assertion si la fonction est terminée par une exception.

La situation dans Java est quelque peu différente. En Java, il n'y a pas de paramètres réels, ce qui signifie que si vous ne pouvez pas utiliser des codes de retour si la fonction a également une valeur de retour. Le résultat est que les exceptions sont utilisées dans beaucoup de cas où un code de retour serait préférable. Et ceux-ci, vous devez savoir, et gérer immédiatement. Pour les choses qui devraient être vraiment des exceptions, Java a java.lang.RuntimeException (qui n'est pas vérifié, statiquement ou autrement).Et il n'a aucune façon de dire qu'une fonction ne peut jamais lancer une exception; il utilise également des exceptions non contrôlées (appelées Error) dans les cas où abandonner le programme serait plus approprié.

Questions connexes