Bonjour à tou(te)s !

en faisant joujou avec les exceptions sous gcc, je suis tombé sur un comportement des plus étranges...
Voici un petit bout de code pour illustrer mon propos :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 
#include <iostream>
#include <string>
using namespace std ;
 
struct Exception
    {
    Exception ()                                               { cout << "Exception::Exception()" << endl ;}
    Exception ( const Exception & e )     : message(e.message) { cout << "Exception::Exception(e) " << message << endl ;}
    Exception ( const string & m )        : message(m)         { cout << "Exception::Exception(s) " << message << endl ;}
    string message ;
    };
 
void failure1 ( const string & s )
    {
    cout << "failure1 : just before throw " << s << endl ; 
    throw Exception( s ) ; // throw just constructed Exception : ok
    }
 
void failure2 ( const string & s )
    {
    static Exception e ;
    e.message = s ;
    cout << "failure2 : just before throw " << s << endl ; 
    throw e ; // throw static Exception : ok
    }
 
void failure3 ( const string & s )
    {
    Exception e( s ) ;
    cout << "failure3 : just before throw " << s << endl ; 
    throw e ; // throw local Exception : KO
    }
 
void sub_failure4 ( const Exception & exception )
    {
    cout << "sub_failure4 : just before throw " << exception.message << endl ; 
    throw Exception( exception ) ; // throw just constructed Exception, but from elder one : KO
    }
 
void failure4 ( const string & message )    
    { 
    cout << "failure4 : just before call sub_failure4" << endl ; 
    sub_failure4( Exception( message )) ;
    }
 
int main ( int argc , const char ** argv )
    {
    try { throw Exception("Exception 0") ;} catch ( Exception e )  { cout << "catch : " << e.message << endl << endl ;} // ok
    try { failure1("Exception 1" )       ;} catch ( Exception e )  { cout << "catch : " << e.message << endl << endl ;} // ok
    try { failure2("Exception 2" )       ;} catch ( Exception e )  { cout << "catch : " << e.message << endl << endl ;} // ok
    if (argc > 1)
    try { failure3("Exception 3" )       ;} catch ( Exception e )  { cout << "catch : " << e.message << endl << endl ;} // KO !
    try { failure4("Exception 4" )       ;} catch ( Exception e )  { cout << "catch : " << e.message << endl << endl ;} // KO !
    }
J'ai 5 scénarios de levée d'exception : les 0, 1 et 2 fonctionnent, les 3 et 4 plantent !
NB : pour pouvoir tester facilement les 3 et 4, je les ai conditionné par la présence d'un argument sur la ligne de commande.

Compilation (avec gcc (i686-posix-dwarf-rev2, Built by MinGW-W64 project) 4.9.0 sous Windows 7 64bits) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
gcc e.cpp -Wall -fexceptions -O2 -lstdc++ -o e.exe
Exécution avec l'exception n°4 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
>e.exe
Exception::Exception(s) Exception 0
Exception::Exception(e) Exception 0
catch : Exception 0
 
failure1 : just before throw Exception 1
Exception::Exception(s) Exception 1
Exception::Exception(e) Exception 1
catch : Exception 1
 
Exception::Exception()
failure2 : just before throw Exception 2
Exception::Exception(e) Exception 2
Exception::Exception(e) Exception 2
catch : Exception 2
 
failure4 : just before call sub_failure4
Exception::Exception(s) Exception 4
sub_failure4 : just before throw Exception 4
Exception::Exception(e) Exception 4
 
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Exécution avec l'exception n°3 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
e.exe x
Exception::Exception(s) Exception 0
Exception::Exception(e) Exception 0
catch : Exception 0
 
failure1 : just before throw Exception 1
Exception::Exception(s) Exception 1
Exception::Exception(e) Exception 1
catch : Exception 1
 
Exception::Exception()
failure2 : just before throw Exception 2
Exception::Exception(e) Exception 2
Exception::Exception(e) Exception 2
catch : Exception 2
 
Exception::Exception(s) Exception 3
failure3 : just before throw Exception 3
Exception::Exception(e) Exception 3
 
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Comme on peut le voir, dans les cas 3 et 4, on n'atteint pas le catch.

Si quelqu'un(e) comprend quelque chose à ce mystère, je suis preneur !

Merci d'avance