C++, __essayer et try/catch/finally
Je me demandais un peu sur le C++ try/catch/finally blocs. J'ai vu ces commandes avec deux caractères de soulignement comme l' __essayer. Mais MVSC projets 2010 également fonctionner sans les traits de soulignement. Alors, quand avez-vous besoin de ces traits de soulignement?
finally
n'est pas en C++ et est vraiment inutile pour correctement écrit de code C++.- Dire que quelque chose est inutile, n'est pas beaucoup vous aider si vous n'avez pas l'appui de votre déclaration avec quelques explications.
finally
est inutile, parce que RAII est une meilleure façon de le faire dans presque tous les cas etscope_guard
prend soin du reste de 0,1%.- Merci pour l'astuce pour RAII. C'est certainement une bonne pratique. Un peu de douleur, si la classe que vous utilisez ne le suivez pas, donc, finalement, pourrait être encore utile. E. g.:
Transaction * t = manager->BegintTransaction()
; try { t->Write("Foo");} catch (...) { LogError(); throw; } finally { manager->CloseTransaction(t); }` de Cette façon, vous n'avez pas besoin de fermer la transaction dans les deuxtry
bloc et dans lecatch
bloc ainsi, juste avant de re-jeter l'exception. - Dans les cas où un type n'a pas été conçu pour le nettoyage et vous êtes d'avoir à manuellement rénovation avec le nettoyage, vous pouvez utiliser quelque chose comme scope_guard à la place. Ici comment votre exemple pourrait ressembler. IMO c'est toujours mieux que de
finally
. Ce n'est pas la norme, mais encore voici la proposition, et vous pouvez vous servir de la 3e partie libs. - des acclamations. C'est assez intéressant. Merci encore.
Vous devez vous connecter pour publier un commentaire.
Sur Windows, les exceptions sont prises en charge au niveau du système d'exploitation. Appelé la gestion Structurée des exceptions (SEH), ils sont l'équivalent d'Unix signaux. Les compilateurs qui génère du code pour Windows prennent généralement avantage de cette, ils utilisent le SEH infrastructure à mettre en place les exceptions C++.
En accord avec la norme C++, le jeter et attraper que les mots clés jamais à lancer et à attraper les exceptions C++. Le correspondant de la SEH code d'exception pour la MSVC compilateur est 0xe06d7343. Les 3 derniers octets sont le code ASCII pour "msc".
L'unifier avec le support de système d'exploitation signifie également que le C++ destructeurs sera appelé pendant le déroulement de pile pour un SEH exception. Le code ne le déroulement est à l'intérieur de Windows et le traite de la gestion structurée des exceptions soulevées par un jeter exactement de la même manière que tout le SEH. Cependant, le compilateur de Microsoft dispose d'une optimisation qui essaie d'éviter de générer le code nécessaire qui garantit que les destructeurs sont appelés dans tous les cas. S'il peut prouver qu'il n'y a pas de jeter de l'instruction à l'intérieur de la portée du bloc de contrôle de l'objet à vie, puis il saute le code d'enregistrement. Ce n'est pas compatible avec asynchrone SEH exceptions, vous devez utiliser le /EHa option de compilation pour supprimer cette optimisation si vous envisagez d'attraper une gestion structurée des exceptions les exceptions.
Il y a beaucoup de SEH types d'exception. Ceux qui peuvent être générés par le système d'exploitation répertoriés dans le ntstatus.h SDK fichier d'en-tête. En outre, vous pouvez l'interopérabilité avec du code qui utilise SEH pour mettre en œuvre leur propre gestion d'exception, ils vont utiliser leur propre code d'exception. Comme .NET, exceptions gérées utiliser le 0xe0434f4d ("com") code d'exception.
Pour attraper SEH exceptions dans un programme C++, vous devez utiliser le non-standard __essayer un mot clé. L' __à l'exception de mot-clé est analogue à la C++ attraper mot-clé. Il a plus de fonctionnalités, vous pouvez spécifier une exception expression de filtre qui détermine si oui ou non un actif d'exception doit être pris. Tout est possible, mais en général, on regarde le passé exception de l'information pour voir si vous êtes intéressé par la manipulation. L' __enfin de mot-clé vous permet d'écrire du code qui s'exécute après que l'exception est gérée. Pas d'équivalent qu'en C++, mais pas rare dans d'autres langues.
Tout cela est assez mal documenté comme l'a souligné dans les commentaires. La preuve est dans le pudding. Voici un exemple de programme que vous pouvez jouer avec. Il montre comment SEH exceptions permet toujours de C++ destructeurs pour être appelé, à condition que vous compilez avec /EHa et comment les exceptions C++ sont mis en œuvre sur le dessus de la SEH. MSVC compilateur nécessaire, exécuter avec Ctrl+F5 pour éviter le débogueur être utile:
De sortie:
__finally
dans un programme C++. Ayant destructeurs pourrait même être la raison, pourquoi il n'y a pas de mot-clé pour toujours exécuter, indépendamment des exceptions levées code.__try
/__except
est d'attraper SEH (windows généré des erreurs) pas pour attraper les exceptions générales.try
/catch
est ce que le C++ standard spécifie pour manutention générale, les exceptions C++.Pour la norme C++ code que vous écrivez, vous devez toujours utiliser
try
/catch
et pas__try
/__except
Aussi,
finally
est pas du C++ Standard spécifié construire, Il travaille pour vous, parce que c'est un Compilateur de Microsoft extension./EHa
(Oui Avec SEH Exceptions) est d'utiliser try/catch gère à la fois: C++ et SEH exceptions. L'inconvénient est quecatch(...)
va gérer SEH, mais vous ne pouvez pas savoir le code de l'exception. Destructeur sera appelé lors de laEHa
est utilisé. Les deuxtry
et__try
ne peuvent pas être mélangés dans la même fonction. Par conséquent, il est préférable d'avoir deux fonctions (l'un appelant l'autre): Une gestiontry
et une autre manipulation__try
(Sans/EHa
)__try/__except
est Microsoft Si vous voulez que votre code compilable avec d'autres compilateurs (pour exemplec g++) (ou) dans un autre système d'exploitation d'éviter de les utiliser, et le bâton avec la standardtry/catch
états