【问题标题】:Does BOOST_NO_EXCEPTIONS guarantee compatibility to -fno-exceptions?BOOST_NO_EXCEPTIONS 是否保证与 -fno-exceptions 的兼容性?
【发布时间】:2015-07-19 20:12:06
【问题描述】:

我想将 Boost.Filesystem 与 -fno-exceptions 一起使用。根据Boost.Filesystem documentation,它声明它支持BOOST_NO_EXCEPTIONS 宏。

不过,下面snippet

#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&, boost::system::error_code)': /.../boost/filesystem/operations.hpp:84:16: 错误: 禁用异常处理,使用 -fexceptions 启用 捕捉 (...) { m_imp_ptr.reset(); }

我在 Mac OSX 上使用 gcc 5 和 boost 1.57 版进行编译(也在类似的 ubuntu 设置上进行了测试)。

我想知道我对BOOST_NO_EXCEPTIONS 的理解是否正确,它应该涵盖-fno-exceptions 的用法,或者它是否只是用于boost::throw_exception 部分?

【问题讨论】:

  • 用 Clang 3.6 为我编译,可以用 GCC 5.1 重现。

标签: c++ exception boost


【解决方案1】:

这是Boost.Filesystem 文档所说的:

文件系统库抛出的所有异常都是通过调用 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 的语义实际上并不是禁用异常,而是:

将所有异常转发到用户定义的非模板版本 boost::throw_exception。

【讨论】:

  • 它承诺使用boost::throw_exception() 的事实明确承诺它支持BOOST_NO_EXCEPTIONS(通过使用Boost Exception)。实现细节是 Boost Exception 的一部分,而不是文件系统库的一部分,这是有道理的。所有这些都很难解决定义BOOST_NO_EXCEPTIONS是否应该使代码-fno-exceptions兼容的问题。
  • @sehe,问题是,代码已经使用try {} catch(...),如果应该在文件系统中的代码周围使用BOOST_NO_EXCEPTIONS来支持-fno-exceptions
  • Boost 的最新版本(至少)使用BOOST_TRYBOOST_CATCH 等,当BOOST_NO_EXCEPTIONS 未定义时扩展为trycatch 等,但@ 987654339@, else if (false) 等等。
【解决方案2】:

嗯,“不”是显而易见的答案,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。不好。

【讨论】:

  • 确实是个笨蛋,因为 BOOST_FILESYSTEM_THROW() 和 filesystem_error 实际上在 boost::filesystem 函数中被广泛使用(尤其是在 operations.cpp 中)。
  • 啊,是的,完全错过了那个。谢谢。
猜你喜欢
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-10
  • 2016-02-02
  • 2013-01-17
  • 2013-09-18
  • 1970-01-01
相关资源
最近更新 更多