35 votes

MSVC - /EHsc vs /EHa (gestion des exceptions synchrones vs asynchrones)

Pourriez-vous dresser une liste des différences et des implications pratiques ? J'ai lu l'article MSDN correspondant, mais ma compréhension des exceptions asynchrones est encore un peu floue.

J'écris une suite de tests en utilisant Boost.Test et mon compilateur émet un avertissement indiquant que EHa doit être activé :

avertissement C4535 : l'appel à _set_se_translator() nécessite /EHa

Le projet lui-même n'utilise que des exceptions simples (de STL) et n'a pas besoin du commutateur /EHa. Dois-je le recompiler avec le commutateur /EHa pour que la suite de tests fonctionne correctement ? Mon sentiment est que je n'ai besoin de /EHa que pour la suite de tests.

50voto

Hans Passant Points 475940

Lorsque vous utilisez /EHsc, le compilateur n'émet du code pour les filtres d'exception que lorsqu'il peut détecter que le code enveloppé dans le bloc try {} est susceptible de lever une exception C++. Un filtre d'exception garantit que le destructeur de tout objet C++ local est appelé lorsque la pile est déroulée pendant le traitement d'une exception. Il permet au RAII de fonctionner.

Il s'agit d'une optimisation, de l'espace et du temps pour le code x86, de l'espace pour le code x64. L'espace parce qu'il peut omettre le code de filtrage des exceptions, qui est modeste d'ailleurs. Le temps parce que sur x86 il peut éviter d'enregistrer le filtre d'exception en entrant dans le bloc try {}. Très modeste aussi. x64 utilise une méthode différente pour trouver les filtres d'exception, basée sur des tables.

La phrase clé du premier paragraphe est "pourrait lever une exception C++". Sous Windows, il existe d'autres sources d'exceptions. Comme le "a" dans /EHa, les exceptions asynchrones qui sont levées par le matériel. Des choses comme les exceptions relatives à la virgule flottante, la division par zéro et la toute puissante exception de violation d'accès. Mais aussi notamment le type d'exceptions qui sont levées par le code avec lequel vous pourriez interopérer. Comme le code géré, en gros tout ce qui s'exécute dans une VM.

Si vous souhaitez que vos objets soient également protégés contre ce type d'exceptions, vous devez utiliser /EHa, qui indique au compilateur de siempre enregistrer le filtre d'exception.

Attention à un effet secondaire désagréable de /EHa, il fait avaler catch(...) todos exceptions. Y compris celles que vous ne devriez jamais attraper, comme AV et SO. Regardez __try/__except et _set_se_translator() si c'est important pour vous.

9voto

9dan Points 2378

Eh bien, sans /EHa, vous ne pouvez pas attraper d'exceptions inattendues et votre programme de test se terminera de manière anormale.

Si le test peut être fait pour une sortie anormale, il vaut mieux ne pas se battre avec /EHa.

En outre, le passage à l'option /EHa entraîne de nombreux effets secondaires, notamment une augmentation de la taille de l'exécutable et une légère baisse des performances. Il s'agit donc d'une modification effective du comportement d'origine.

L'utilisation ou non de /EHa est une décision importante qui est généralement prise au stade de la conception du programme.

Selon moi, les problèmes liés à la rédaction des cas de test sont plutôt insignifiants pour modifier cette décision.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X