2015-06-16 22 views
7

Il gestore di catch non viene eseguito. Ma perché?Perché il blocco catch di questo codice non viene eseguito?

Seviene avviato prima del blocco try, viene eseguito il gestore catch.

Se il tipo di blocco catch non corrisponde al tipo generato, il programma termina spiegando che il thread termina con un'eccezione non rilevata, suggerendo che l'eccezione viene gestita, tuttavia il blocco catch non viene eseguito.

#include <iostream> 
#include <thread> 

using namespace std; 

void do_work() {} 

int main() { 
    std::cerr << "RUNNING" << std::endl; 
    try { 
    thread t(do_work); 
    std::cerr << "THROWING" << std::endl; 
    throw logic_error("something went wrong"); 
    } catch (logic_error e) { 
    std::cerr << "GOTCHA" << std::endl; 
    } 

    return 0; 
} 

comando Compila:

c++ -std=c++14 -pthread -pedantic -Wall -Wextra -O0 scratch.cpp -o scratch 
+2

Si prega di indentare il codice prima di premere il pulsante di invio – bhavesh

+0

Perché sulla terra questo ha un downvote? \ * scratches head \ * –

+0

@LightnessRacesinOrbit Qualcuno probabilmente ha downvoted indietro quando il codice ha interrotto la formattazione. – user2079303

risposta

5

Si è dimenticato di unirsi alla discussione:

try { 
    thread t(do_work); 
    t.join();         // <<< add this 
    std::cerr << "THROWING" << std::endl; 
    throw logic_error("something went wrong"); 
} catch (logic_error e) { 
    std::cerr << "GOTCHA" << std::endl; 
} 

A joinable thread that goes out of scope, causes terminate to be called. Quindi, è necessario chiamare sia join o detach prima che vada fuori ambito.

2

In C++ 11, 30.3.1.3, filo distruttore standard dice

If unibili altrimenti non cfu() quindi terminare(), e segg. [Nota: il distacco implicito o l'unione di un thread joinable() nel suo distruttore può comportare un debug di errori di correttezza (per la rimozione) o di prestazioni (per join) rilevati solo quando viene sollevata un'eccezione. Pertanto, il programmatore deve assicurarsi che il distruttore non venga mai eseguito mentre il thread è ancora unificabile. Nota -end]

Così il vostro programma terminate s una volta che il distruttore thread viene chiamato perché la portata finisce e la logica catch non viene mai eseguito.

Se si desidera che il programma per catturare l'eccezione fuori del campo di applicazione del thread, ma gettare mentre il thread è ancora joinable, è necessario prenderlo nel campo di applicazione del filo stesso, join o detach il filo e rethrow qualunque è stato catturato

try 
{ 
    std::thread t(foo); 
    try 
    { 
    std::cerr << "THROWING" << std::endl; 
    throw std::logic_error("something went wrong"); 
    } 
    catch (...) // catch everything 
    { 
    t.join(); // join thread 
    throw; // rethrow 
    } 
    t.join(); 
} 
catch (std::logic_error & e) 
{ 
    std::cerr << "GOTCHA: " << e.what() << std::endl; 
} 
Problemi correlati