BOOST_NO_EXCEPTIONS是否保证与-fno-exceptions的兼容性?

时间:2015-05-08 19:51:23

标签: c++ exception boost

我想将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部分?

2 个答案:

答案 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(); }
} 

如果您阅读thisBOOST_NO_EXCEPTIONS的语义实际上并非禁用例外,但是:

  

将所有例外转发给用户定义的非模板版本   升压:: throw_exception。