Y a-t-il une différence entre throw()
et noexcept
autre que la vérification au moment de l'exécution et de la compilation, respectivement?
Cet article Wikipedia C ++ 11 suggère que les spécificateurs de jet C ++ 03 sont obsolètes.
Pourquoi donc, est-il noexcept
assez capable de couvrir tout cela au moment de la compilation?
[Remarque: j'ai vérifié cette question et cet article , mais je n'ai pas pu déterminer la raison solide de l'abandon.]
noexcept
des vérifications d'exécution peuvent également être nécessaires . La principale différence entre eux est que la rupturenoexcept
provoquestd::terminate
tandis que la rupturethrow
provoquestd::unexpected
. Également un comportement de déroulement de pile légèrement différent dans ces cas.Réponses:
Les spécificateurs d'exceptions étaient obsolètes car les spécificateurs d'exceptions sont généralement une mauvaise idée .
noexcept
a été ajouté parce que c'est la seule utilisation raisonnablement utile d'un spécificateur d'exception: savoir quand une fonction ne lèvera pas d'exception. Cela devient donc un choix binaire: des fonctions qui lanceront et des fonctions qui ne lanceront pas.noexcept
a été ajouté plutôt que de simplement supprimer tous les spécificateurs de jet autrement quethrow()
parce qu'ilnoexcept
est plus puissant.noexcept
peut avoir un paramètre qui au moment de la compilation se résout en booléen. Si le booléen est vrai, alors lesnoexcept
bâtons. Si le booléen est faux, alorsnoexcept
ne colle pas et la fonction peut lancer.Ainsi, vous pouvez faire quelque chose comme ceci:
CreateOtherClass
Lève- t-il des exceptions? Cela pourrait, siT
le constructeur par défaut de le peut. Comment le dire? Comme ça:Ainsi,
CreateOtherClass()
lancera ssi le constructeur par défaut du type donné lance. Cela résout l'un des problèmes majeurs avec les spécificateurs d'exception: leur incapacité à propager la pile d'appels.Vous ne pouvez pas faire ça avec
throw()
.la source
noexcept
. Je n'ai jamais utilisé dethrow()
spécificateur, jamais et j'essaie de déterminer s'ilnoexcept
fournit réellement un avantage (autre que la documentation vérifiée par le compilateur).std::terminate
. ce qui est bien pire ! le code peut se faufiler dans les versions qui ont des fonctions marquéesnoexcept
et au moment de l'exécution (c'est-à-dire sur les sites des clients) les violations sont détectées. Je voulais dire que le compilateur garantit de générer du code qui ne lève pas d' exceptions en premier lieu.throws()
alors si une exception est levée, la pile doit être déroulée jusqu'à la portée de cette fonction (de sorte que toutes les variables automatiques de la fonction sont détruites) à quel pointterminate()
est appelée (viaunexpected()
). Si une fonction est marquée,noexcept
alors si une exception est levée, terminate est appelé (le déroulement de la pile est un détail défini par l'implémentation).noexcept
n'est pas vérifié au moment de la compilation.Lorsqu'une fonction qui est déclarée
noexcept
outhrow()
tente de lever une exception, la seule différence est que l'on appelleterminate
et que les autres appelsunexpected
et ce dernier style de gestion des exceptions est effectivement obsolète.la source
throw()
/noexcept
, la vérification du temps de compilation garantit qu'un remplacement a également.std::unexpected()
est appelée par le runtime C ++ lorsqu'une spécification d'exception dynamique est violée: une exception est levée à partir d'une fonction dont la spécification d'exception interdit les exceptions de ce type.std::unexpected()
peut également être appelé directement depuis le programme.Dans les deux cas,
std::unexpected
appelle le fichier actuellement installéstd::unexpected_handler
. Lesstd::unexpected_handler
appels par défautstd::terminate
.la source