我想将Boost.Filesystem与-fno-exceptions
一起使用。根据{{3}},它声明它支持BOOST_NO_EXCEPTIONS
宏。
但是,以下Boost.Filesystem documentation:
#define BOOST_NO_EXCEPTIONS
#include <boost/filesystem.hpp>
int main() {}
编译:
g ++ -fno-exceptions boost_test.cpp
给出错误:
/.../ boost / filesystem / operations.hpp:在构造函数中 'boost :: filesystem :: filesystem_error :: filesystem_error(const string&amp;, 提高::系统::错误代码)“: /.../boost/filesystem/operations.hpp:84:16:错误: 禁用异常处理,使用-fexceptions启用 catch(...){m_imp_ptr.reset(); }
我在Mac OSX上使用gcc 5和boost 1.57进行编译(也在类似的ubuntu设置上进行了测试)。
我想知道我对BOOST_NO_EXCEPTIONS
的理解是否正确,因为它应该涵盖-fno-exceptions
的用法,或者它是否只适用于boost::throw_exception
部分?
答案 0 :(得分:9)
嗯,“不”是明显的答案,g ++无法处理filesystem_error类。 boost / filesystem / config.hpp中有一个humdinger:
// 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
此宏在libs / filesystem / src / operations.cpp中广泛使用以引发异常。这是一个表演者。
Fwiw,你的示例程序只有出现才能在clang和MSVC ++中正确编译,他们只在后端抱怨必须发出异常处理代码,g ++在它的前端做到了。 clang / msvc ++没有对此示例代码提出任何抱怨,因为之前已经发出了异常处理代码,而且在构建boost库时也是如此。
这说明了您的方法的另一个严重问题,您最初可能在没有-fno-exceptions的情况下构建了boost。不好。
答案 1 :(得分:0)
这是文档所说的Boost.Filesystem:
Filesystem Library抛出的所有异常都是通过调用boost :: throw_exception()来实现的。因此,在编译文件系统源文件时,确切的行为可能会因BOOST_NO_EXCEPTIONS而异。
根据我的理解,它并不能说它支持BOOST_NO_EXCEPTIONS
当我在文件系统目录下执行egrep -r BOOST_NO_EXCEPTIONS
时,我什么都没找到
在我阅读源代码后,它支持我的猜测。在代码中有许多地方使用try { ... } catch(...)
。您也可以从错误消息中了解到。这是一个例子:
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(); }
}
如果您阅读this,BOOST_NO_EXCEPTIONS
的语义实际上并非禁用例外,但是:
将所有例外转发给用户定义的非模板版本 升压:: throw_exception。