2015-08-18 5 views
3

Il est connu que Windows SEH ne va pas avec le mécanisme de gestion des exceptions C++. Nous ne pouvons pas utiliser try et __try en fonction unique. Cela conduira à une erreur du compilateur:Mélanger '__try' et 'try' dans une seule fonction - Par Lambda

__try 
{ 
    try 
    { 
     MayThrowCPPException_OR_SEH(); 
    } 
    catch(...) 
    { 
    } 
} 
__except(EXCEPTION_EXECUTE_HANDLER) 
{ 
} 

Il va rendre:

C2713: Only one form of exception handling permitted per function.

Une option, que la plupart des gens n'aiment pas est "Oui avec des exceptions SEH (/EHa)" option du compilateur . Cela facilitera C++ try/catch pour gérer les deux exceptions. Nous devons mettre cette fonction dans un fichier séparé, et mettre /EHa seulement pour ce fichier source.

Une autre option est de mettre try (ou __try) dans une fonction et une autre fonction qui aura __try (ou try).

Question commence Tout en essayant de faire ce qui précède, j'ai essayé en ayant juste un C++ lambda pour tromper le compilateur. Voici ce que je faisais:

auto call_this =[] 
{ 
    MayThrowCPPException_OR_SEH(); 
    // C++ exception handling here. 
}; 
__try 
{ 
    call_this(); 
} 
__except(...) 
{ 
} 

Et bien sur cette compilé VC 2013 mise à jour 5.

Est-il sûr de le faire?

+0

cela ne compile pas sur mon VS 2013 .. –

+0

Quelle erreur obtenez-vous? – Ajay

+0

que le lamda lui-même requiers stack déroulement, ce qui est la raison pour laquelle vous vouliez utiliser lambda en premier lieu –

Répondre

1

Oui, ceci est sûr. Le corps lambda est juste une méthode operator() d'un type lambda non nommé. Cette méthode a le gestionnaire d'exceptions C++. La fonction externe a le gestionnaire SEH.

+0

Je ne serais pas couronner cette réponse aussi correcte si vite. Je n'ai pas pu créer ce code sur mon VS, mais j'ai peur que lorsque l'exception produite par le matériel est lancée, il n'appelle pas les destructeurs de tous les objets qu'il trouve, comme le fait l'exception C++ ordinaire. Je n'ai pas pu le vérifier puisque je ne peux pas compiler le code, mais c'est quelque chose que l'on doit vérifier avant de dire que c'est sûr. le programme ne peut pas tomber en panne, mais les objets à l'intérieur du lambda peuvent être dans une très mauvaise codition. –

+0

@DavidHaim: En effet. La fonctionnalité SEH existe au niveau du système d'exploitation. Le système d'exploitation ne connaît pas les destructeurs, donc il ne les appellera pas. Mais ce n'est pas lié au problème ici (mélange des gestionnaires d'exception). C'est pourquoi je dis que cette méthode est sûre: elle supposait que vous aviez déjà du code SEH-safe. – MSalters

+0

@DavidHaim, je suis d'accord avec le modèle RAII. __try n'est pas fait pour ça, et je n'ai pas dit ça. – Ajay