Non, l'exception n'est pas lancée dans le destructeur. Elle est lancée indirectement depuis le destructeur.
Tu pinailles, ça revient exactement au même...
Maintenant, je m'attendais à ce que tu vienne avec une solution qui est encore pire qu'un segfault : attraper l'exception dans le destructeur, et continuer comme si de rien n'était (oui, cracher dans std::cerr revient à ne rien faire).
Voir mon autre post en réponse à ckyl.
Premièrement, parce qu'on ne sait pas dans quel état on est
De mon point de vue, c'est justement le travail du destructeur de faire quelque chose d'approprié quand il lève une exception. Justement pour avoir un état valide à la fin. Et, si ce n'est pas possible, appeler std::terminate dans le destructeur est acceptable. Une autre solution pas trop mal, c'est de donner un "handler" à l'objet (pointeur de fonction / foncteur), qu'il peut appeler en cas d'erreurs sur une tâche asynchrone (y compris dans le destructeur). Comme ça, le programme peut faire ce qui lui semble approprié dans ce cas (et il est certainement mieux placé que le destructeur peut savoir ce qui est "le mieux" à faire d'ailleurs).
C'est d'ailleurs pour ça que le programme se termine quand une exception est balancée depuis un destructeur : c'est la panique.
Non, ton exemple s'est retrouvé dans std::terminate parce qu'une exception n'a pas été attrapée : l'exception lancée dans le destructeur de l'objet du premier morceau de code du main, après le catch (celui qui affiche "Catched exception"). Le deuxième morceau de code du main n'est, par conséquent, pas exécute (s'il était, le catch serait exécuté comme attendu et "That can't be catched" serait affiché sur la sortie standard).
Appeler flush et close explicitement dans l'appelant ne résout pas le problème...
[^] # Re: finally
Posté par Arcruxe . En réponse à la dépêche Peuch-peuch Cinq Cinq, pour PHP 5.5. Évalué à 0.
Tu pinailles, ça revient exactement au même...
Voir mon autre post en réponse à ckyl.
De mon point de vue, c'est justement le travail du destructeur de faire quelque chose d'approprié quand il lève une exception. Justement pour avoir un état valide à la fin. Et, si ce n'est pas possible, appeler std::terminate dans le destructeur est acceptable. Une autre solution pas trop mal, c'est de donner un "handler" à l'objet (pointeur de fonction / foncteur), qu'il peut appeler en cas d'erreurs sur une tâche asynchrone (y compris dans le destructeur). Comme ça, le programme peut faire ce qui lui semble approprié dans ce cas (et il est certainement mieux placé que le destructeur peut savoir ce qui est "le mieux" à faire d'ailleurs).
Non, ton exemple s'est retrouvé dans std::terminate parce qu'une exception n'a pas été attrapée : l'exception lancée dans le destructeur de l'objet du premier morceau de code du main, après le catch (celui qui affiche "Catched exception"). Le deuxième morceau de code du main n'est, par conséquent, pas exécute (s'il était, le catch serait exécuté comme attendu et "That can't be catched" serait affiché sur la sortie standard).
Appeler flush et close explicitement dans l'appelant ne résout pas le problème...