Dans le code suivant, la fonction foo
s'appelle récursivement une fois. L'appel interne provoque une violation d'accès. L'appel externe intercepte l'exception.Est-ce que __finally est supposé s'exécuter après EXCEPTION_CONTINUE_SEARCH?
#include <windows.h>
#include <stdio.h>
void foo(int cont)
{
__try
{
__try
{
__try
{
if (!cont)
*(int *)0 = 0;
foo(cont - 1);
}
__finally
{
printf("inner finally %d\n", cont);
}
}
__except (!cont? EXCEPTION_CONTINUE_SEARCH: EXCEPTION_EXECUTE_HANDLER)
{
printf("except %d\n", cont);
}
}
__finally
{
printf("outer finally %d\n", cont);
}
}
int main()
{
__try
{
foo(1);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("main\n");
}
return 0;
}
Le résultat attendu ici devrait être
inner finally 0
outer finally 0
inner finally 1
except 1
outer finally 1
Cependant, outer finally 0
manque manifestement de la production réelle. Est-ce un bug ou y a-t-il des détails que je néglige? Pour l'exhaustivité, arrive avec VS2015, compilant pour x 64. Étonnamment, cela n'arrive pas sur x86, ce qui me fait croire que c'est vraiment un bug.
Cela pourrait techniquement tomber sous le coup d'un comportement indéfini, comme vous l'affectez à un pointeur nul. Avez-vous essayé de lancer une exception régulière en utilisant 'RaiseException'? – OmnipotentEntity
Eh bien, pas bon. Ce n'est pas un nouveau problème, VS2013 se comporte de la même manière. On dirait une limitation structurelle de/SAFESEH pour moi, spécifique à la récursivité, ça marche bien dans un cas non récursif. Assez douteux n'importe qui ici peut résoudre ce problème, mieux pour envoyer un ping à connect.microsoft.com à ce sujet. –
@OmnipotentEntity: L'affectation à un pointeur nul est un comportement * non défini, en ce qui concerne la norme de langage C++. Sur la plate-forme Windows, cependant, ceci est bien défini: L'instruction déclenche une violation d'accès, qui est communiquée au code utilisateur via une exception SEH. – IInspectable