【问题标题】:What is the difference between declaring function as __attribute__(nothrow) and `throw()`将函数声明为 __attribute__(nothrow) 和 `throw()` 有什么区别
【发布时间】:2013-10-19 23:23:24
【问题描述】:

在使用支持 gnu 扩展的 C++ 编译器(例如 Linux 上的 g++ 本身;C++03)时,将函数声明为 __attribute__(nothrow)throw() 有什么区别。

据我了解,这两种变体都是说编译器这个函数不会抛出异常。但实现可能不同

编译器将如何使用这些信息?

如果我在 nothrow 或 throw() 函数内运行时抛出异常,并且这个异常会上升到函数中怎么办?函数会进一步传递异常还是隐藏异常或其他?

【问题讨论】:

  • __attribue__ 是一个编译器扩展。 throw() 是标准的一部分。前者可能是错误的,我认为后者已被弃用,因此不作为答案发布。
  • @JohnDibling 真的是未定义的行为吗?我以为它调用了std::set_unexpected 中指定的处理程序
  • @erikkallen 如果是throw(),则调用std::unexpected(),如果是noexcept(true),则调用std::terminate()
  • @erikkallen:我收回我声明的那一部分。 @简单是正确的。见 15.4/9-10。

标签: c++ exception-handling


【解决方案1】:

有几个区别:

  1. __attribute__((...)) 语法是 gnu 编译器扩展,不完全可移植,throw() 由 C++ 标准定义。

  2. 如果我没看错,__attribute__((nothrow)) 会告诉编译器它可以安全地假设函数不会引发异常,并且可能会省略发出一些异常处理所需的代码(这是在调用边)。另一方面,throw() 隐式捕获由相关函数产生的所有异常,并在捕获某些内容时通过首先调用意外异常处理程序来终止程序,默认情况下调用 terminate()(这发生在被调用方边)。

在编程方面,throw() 更有用,因为它可以保护您的代码不被异常静默跳过。当我处理一个使用异常的项目时,我会在我编写的每个函数中添加throw()

但是请注意,__attribute__((nothrow))throw() 都不会导致编译器实际检查是否不会抛出异常。这很不幸,但 C++ 标准明确规定编译器不得在使用 throw() 声明的函数内抛出错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-20
    • 2019-12-15
    • 2012-02-27
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多