Problème de catch d'exception

Le problème exposé dans ce sujet a été résolu.

Bonjours à tous,

j'étais en train de tester les exceptions des streams en c++, j'ai donc écris ce code :

 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
#include <iostream>
#include <climits>
#include "person.h"

void cin_state();

int main()
{
    std::cin.exceptions(std::ios::failbit);
    int x;

    cin_state();
    try
    {
    std::cin >> x;
    }
    catch (std::ios_base::failure const &problem)
    {
    cin_state();
    std::cout << problem.what() << std::endl;
    std::cin.clear();
    cin_state();
    std::cin.ignore(INT_MAX, '\n');
    }

    std::cout << x << std::endl;
    cin_state();

    return 0;
}

void cin_state()
{
    std::cout << "good  : " << std::cin.good() << std::endl;
    std::cout << "eof   : " << std::cin.eof() << std::endl;
    std::cout << "fail  : " << std::cin.fail() << std::endl;
    std::cout << "bad   : " << std::cin.bad() << std::endl;
    std::cout << "state : " << std::cin.rdstate() << std::endl;
}

mais le block try n'attrape pas l'exception et le programme me sort ça

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# ludovic at Tardis in ~workspace/C++/bordel [20:21:21]
$ ./executable 
good  : 1
eof   : 0
fail  : 0
bad   : 0
state : 0
ao
terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_ios::clear
[1]    8837 abort (core dumped)  ./executable

Si vous pourriez m'expliquer pourquoi ça ne fonctionne pas cela me sera d'une grande aide.

Merci d'avance pour vos réponces :)

+0 -0

Salut, c'est std::istream::clear() qui a lancé une exception dans ton catch() :p .

Ilearn32

Non, sinon le premier appel à cin_state dans le bloc catch (qui se trouve avant le clear) aurait affiché du texte juste après la saisie.

C'est un comportement assez étrange, et je ne saurai te dire la cause, d'après la doc ça a l'air correct. Visiblement, il suffit d'attraper une instance de std::exception plutôt qu'autre chose :

13
14
15
16
17
18
19
try
{
    std::cin >> x;
}
catch (std::exception const &problem)
{
    // ...

Ok, ça pue grave du cul. Cela ressemble à un bug crade dans g++ :

 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
#include <typeinfo>
#include <iostream>
#include <climits>

void cin_state();

int main()
{
    std::cin.exceptions(std::ios::failbit);
    int x;
    try
    {
        std::cin >> x;
    }
    catch (std::exception const &problem)
    {
        std::cout << typeid(std::ios_base::failure).name() << std::endl;
        std::cout << typeid(problem).name() << std::endl;
        std::cout << problem.what() << std::endl;
    }

    return 0;
}

void cin_state()
{
    std::cout << "good  : " << std::cin.good() << std::endl;
    std::cout << "eof   : " << std::cin.eof() << std::endl;
    std::cout << "fail  : " << std::cin.fail() << std::endl;
    std::cout << "bad   : " << std::cin.bad() << std::endl;
    std::cout << "state : " << std::cin.rdstate() << std::endl;
}

Résultat :

1
2
3
NSt8ios_base7failureB5cxx11E
NSt8ios_base7failureE
basic_ios::clear

On dirait que les namespaces ont craqué leur slip.

BINGO : https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145

@Ludo Bike: J'ai testé ton code avec Code::Blocks et j'ai la même chose que toi, finalement. Puis la doc dit ça:

if an exception is thrown, the object is in a valid state. It throws an exception of member type failure if the resulting error state flag is not goodbit and member exceptions was set to throw for that state. Any exception thrown by an internal operation is caught and handled by the function, setting badbit. If badbit was set on the last call to exceptions, the function rethrows the caught exception.

D'après ce que j'ai compris,comme tu as réglé au départ le comportement de std::cin en cas d'exception, les fonctions relancent l'exception(pas sûr, quoi qu'il en soit, il faut vraiment que je révise mon anglais :( ).

Où c'est vraiment un bug de g++, ou c'est le compilateur de Visual Studio qui ne respecte pas les normes :p .

PS : testé avec code::blocks compilateur 5.2 avec l'option -std=c++14 :p .

PS2 : Bravo Ksass `Peuk pour avoir trouvé la solution :) .

+0 -0

Où c'est vraiment un bug de g++, ou c'est le compilateur de Visual Studio qui ne respecte pas les normes :p .

PS : testé avec code::blocks compilateur 5.2 avec l'option -std=c++14 :p .

Ilearn32

  • Testé avec GCC 5.3 : crash.
  • Testé avec GCC 6.0 : crash.
  • Testé avec clang 3.7 : fonctionne.

Donc je pense bien que ce soit un bug de GCC.

Ok donc du coup il y a un problème avec gcc qui fait que l'exception doit etre catch comme étant une std::exeption alors que c'est une std::ios_base::exeption.

J'espère qu'il vont le corriger dans une prochaine version, en tous cas merci de vos réponces :)

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte