4

What is the difference between declaring function as __attribute__(nothrow) and throw() when using C++ compiler with support of gnu extensions (e.g. g++ itself on Linux; C++03).

As I understand, both variants are to say compiler that this function will not throw exceptions. But implementations may be different

How will compiler use this information?

What if I will throw exception while running inside the nothrow or throw() function and this exception will go up to the function? Will function pass exception further or it will hide exception or something else?

osgx
  • 90,338
  • 53
  • 357
  • 513
  • 3
    `__attribue__` is a compiler extension. `throw()` is part of the Standard. Could be wrong about the former, and I think the latter was deprecated, so not posting as answer. – John Dibling Oct 11 '13 at 19:22
  • @JohnDibling Is it really undefined behavior? I thought it invoked the handler specified in ```std::set_unexpected``` – erikkallen Oct 11 '13 at 19:33
  • @erikkallen if it's `throw()` then `std::unexpected()` is called and if its `noexcept(true)` then `std::terminate()` is called. – Simple Oct 11 '13 at 19:37
  • Have a look at http://stackoverflow.com/questions/12833241/difference-between-c03-throw-specifier-c11-noexcept –  Oct 11 '13 at 19:43
  • @erikkallen: I retract that part of my statement. @ Simple is correct. See 15.4/9-10. – John Dibling Oct 11 '13 at 19:46

1 Answers1

5

There are several differences:

  1. The __attribute__((...)) syntax is a gnu compiler extension, which is not exactly portable, throw() is defined by the C++ standard.

  2. If I read it correctly, __attribute__((nothrow)) tells the compiler that it can safely assume that a function won't raise an exception, and can possibly omit emitting some code necessary for exception handling (this is on the caller side). throw(), on the other hand, implicitely catches all exceptions that arise from the function in question, and terminates the program when something is caught by calling first the unexpected exception handler, which by default calls terminate() (this happens on the callee side).

In terms of programming, throw() is the much more useful, because it can safeguard your code from being silently skipped by an exception. When I work on a project that uses exceptions, I make a point to add throw() to every single function I write.

Note, however, that neither __attribute__((nothrow)) nor throw() will cause the compiler to actually check whether no exception can be thrown. This is quite unfortunate, but the C++ standard explicitely says that the compiler must not throw an error on a throw within a function declared with throw().

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106