Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I really use noexcept?

The noexcept keyword can be appropriately applied to many function signatures, but I am unsure as to when I should consider using it in practice. Based on what I have read so far, the last-minute addition of noexcept seems to address some important issues that arise when move constructors throw. However, I am still unable to provide satisfactory answers to some practical questions that led me to read more about noexcept in the first place.

  1. There are many examples of functions that I know will never throw, but for which the compiler cannot determine so on its own. Should I append noexcept to the function declaration in all such cases?

    Having to think about whether or not I need to append noexcept after every function declaration would greatly reduce programmer productivity (and frankly, would be a pain in the neck). For which situations should I be more careful about the use of noexcept, and for which situations can I get away with the implied noexcept(false)?

  2. When can I realistically expect to observe a performance improvement after using noexcept? In particular, give an example of code for which a C++ compiler is able to generate better machine code after the addition of noexcept.

    Personally, I care about noexcept because of the increased freedom provided to the compiler to safely apply certain kinds of optimizations. Do modern compilers take advantage of noexcept in this way? If not, can I expect some of them to do so in the near future?

like image 361
void-pointer Avatar asked May 28 '12 16:05

void-pointer


People also ask

When should you use Noexcept?

E. 12: Use noexcept when exiting a function because of a throw is impossible or unacceptable. you don't care in case of an exception. You are willing to crash the program because you can not handle an exception such as std::bad_alloc due to memory exhaustion.

Should I use Noexcept everywhere?

In general, you should use noexcept when you think it will actually be useful to do so. Some code will take different paths if is_nothrow_constructible is true for that type. If you're using code that will do that, then feel free to noexcept appropriate constructors.

Is Noexcept required?

Explicit instantiations may use the noexcept specifier, but it is not required. If used, the exception specification must be the same as for all other declarations.

What is the point of Noexcept C++?

The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions. It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.


1 Answers

I think it is too early to give a "best practices" answer for this as there hasn't been enough time to use it in practice. If this was asked about throw specifiers right after they came out then the answers would be very different to now.

Having to think about whether or not I need to append noexcept after every function declaration would greatly reduce programmer productivity (and frankly, would be a pain).

Well, then use it when it's obvious that the function will never throw.

When can I realistically expect to observe a performance improvement after using noexcept? [...] Personally, I care about noexcept because of the increased freedom provided to the compiler to safely apply certain kinds of optimizations.

It seems like the biggest optimization gains are from user optimizations, not compiler ones due to the possibility of checking noexcept and overloading on it. Most compilers follow a no-penalty-if-you-don't-throw exception handling method, so I doubt it would change much (or anything) on the machine code level of your code, although perhaps reduce the binary size by removing the handling code.

Using noexcept in the big four (constructors, assignment, not destructors as they're already noexcept) will likely cause the best improvements as noexcept checks are 'common' in template code such as in std containers. For instance, std::vector won't use your class's move unless it's marked noexcept (or the compiler can deduce it otherwise).

like image 85
Pubby Avatar answered Sep 17 '22 08:09

Pubby