2015-05-08 3 views
15

Desidero utilizzare Boost.Filesystem insieme a -fno-exceptions. Secondo lo Boost.Filesystem documentation, afferma che supporta la macro BOOST_NO_EXCEPTIONS.BOOST_NO_EXCEPTIONS garantisce la compatibilità con le eccezioni?

Tuttavia, il seguente snippet:

#define BOOST_NO_EXCEPTIONS 

#include <boost/filesystem.hpp> 

int main() {} 

compilato con:

g++ -fno-exceptions boost_test.cpp

dà l'errore:

/.../boost/filesystem/operations.hpp: In constructor 'boost::filesystem::filesystem_error::filesystem_error(const string&, boost::system::error_code)': /.../boost/filesystem/operations.hpp:84:16: error: exception handling disabled, use -fexceptions to enable catch (...) { m_imp_ptr.reset(); }

compilo usando GCC 5 e spinta versione 1.57 su Mac OSX (testato anche su configurazioni di Ubuntu simili).

Mi chiedo se la mia comprensione di BOOST_NO_EXCEPTIONS è corretta in quanto dovrebbe coprire l'utilizzo di -fno-exceptions o se è semplicemente lì per la parte boost::throw_exception?

+3

Compiles per me con Clang 3.6, può essere riprodotto con GCC 5.1. – Columbo

risposta

8

Bene, "no" è la risposta ovvia, g ++ non può trattare con la classe filesystem_error. C'è un humdinger in boost/filesystem/config.hpp:

// throw an exception ----------------------------------------------------------------// 
// 
// Exceptions were originally thrown via boost::throw_exception(). 
// As throw_exception() became more complex, it caused user error reporting 
// to be harder to interpret, since the exception reported became much more complex. 
// The immediate fix was to throw directly, wrapped in a macro to make any later change 
// easier. 

#define BOOST_FILESYSTEM_THROW(EX) throw EX 

Questa macro sono ampiamente usate in libs/filesystem/src/operations.cpp per generare eccezioni. Questo è uno spettacolo-tappo.

FWIW, il vostro programma di esempio solo sembra per compilare correttamente clang e MSVC++, si lamentano solo nella loro back-end di dover emettere il codice di gestione delle eccezioni, g ++ lo fa nel suo front-end. Nessun reclamo da clang/msvC++ per questo codice di esempio poiché quel codice di gestione delle eccezioni era già stato emesso precedentemente, quando le librerie di boost sono state create.

Che dimostra un altro grave problema con il vostro approccio, probabilmente avete originariamente costruito boost senza -fno-eccezioni in effetti. Non bene.

+2

Votato, molto interessante! Inoltre, TIL "humdinger". – inf

+0

Un humdinger in effetti, perché BOOST_FILESYSTEM_THROW() e filesystem_error sono infatti ampiamente utilizzati nelle funzioni boost :: filesystem (in particolare in operations.cpp). – Jeremy

+0

Ah, sì, mi sono completamente perso. Grazie. –

0

Questo è ciò che Boost.Filesystem la documentazione dice:

All exceptions thrown by the Filesystem Library are implemented by calling boost::throw_exception(). Thus exact behavior may differ depending on BOOST_NO_EXCEPTIONS at the time the filesystem source files are compiled.

Nella mia comprensione, in realtà non dicono che supporta BOOST_NO_EXCEPTIONS

E quando ho fatto un egrep -r BOOST_NO_EXCEPTIONS sotto la directory del file system, non ho trovato nulla

E dopo aver letto il codice sorgente, supporta la mia ipotesi. Ci sono molti posti che usano try { ... } catch(...) nel codice. Puoi anche dire dal messaggio di errore che hai ricevuto. Ecco un esempio:

filesystem_error(
    const std::string & what_arg, const path& path1_arg, 
    const path& path2_arg, system::error_code ec) 
    : system::system_error(ec, what_arg) 
{  
    try 
    {  
    m_imp_ptr.reset(new m_imp); 
    m_imp_ptr->m_path1 = path1_arg; 
    m_imp_ptr->m_path2 = path2_arg; 
    }  
    catch (...) { m_imp_ptr.reset(); } 
} 

E se leggete this, la semantica di BOOST_NO_EXCEPTIONS è in realtà non invalidanti eccezioni, ma:

forwarding all exceptions to a user-defined non-template version of boost::throw_exception.

+1

Il fatto che prometta di usare 'boost :: throw_exception()' promette esplicitamente che supporta 'BOOST_NO_EXCEPTIONS' (usando Boost Exception in tutto). È logico che i dettagli di implementazione siano parte di Boost Exception, non della libreria di file system.Tutto questo difficilmente risolve la questione se definire 'BOOST_NO_EXCEPTIONS' dovrebbe rendere il codice' -fno-exceptions' compatibile. – sehe

+0

@sehe, il fatto è che il codice usa già 'try {} catch (...)', Se si deve usare BOOST_NO_EXCEPTIONS attorno al codice nel filesystem per supportare '-fno-exceptions'. –

+0

Le versioni recenti (almeno) di Boost usano 'BOOST_TRY',' BOOST_CATCH', ecc, che si espandono in 'try',' catch', etc quando 'BOOST_NO_EXCEPTIONS' non è definito, ma a' if (true) ',' altrimenti se (false) 'etc quando è. – Jeremy