C ++ optimization throw ()

According to C ++ Optimization ,

Use the empty exception specification (i.e. add throw () to the declaration) for functions that you are sure will never throw exceptions.

What if I know that 90% of my methods will not throw an exception? It seems unconventional and verbose to add throw () to all of these methods. If not, what are the benefits? Or am I not understanding something?

+5
source share
2 answers

C ++ 11 introduced noexcept , throw somewhat outdated (and according to this is less efficient)

noexcept is an improved version of throw (), which is deprecated in C ++ 11. Unlike throw (), noexcept does not call std :: unexpected and may or may not unwind the stack, which potentially allows the compiler to implement noexcept without running time overhead throw ().

When the specification of an empty throw is violated, your program will be interrupted; this means that you should declare your functions as non-throwing only when they have no guarantee of throwing exception.

Finally, you need a move constructor that doesn't have to jerk (set with noexcept ) to be able to use the r-value of the ref version of std::vector<T>::push_back (see best explanation here )

+8
source

The throw() standard does not increase optimizability.

If the method is marked as throw() , then the compiler is forced to check whether an exception is thrown from the method and unwinds the stack - just as if the function is not marked as throw() . The only real difference is that for a function labeled throw() , a global unexpected_handler will be called (which usually calls terminate() ) when the exception leaves the function, unwinding the stack to that level, instead of behavior for functions without an exception specification, which is usually will handle the exception.

For pre-C ++ 11 code, Sutter and Alexandrescu in "C ++ Coding Standards" suggested:

Avoid exception specifications.

Exclude from these specifications: Do not write a specification exception for your functions if you are not forced to (because other code that you cannot change has already introduced them; see Exceptions).

...

A common, but nonetheless incorrect belief is that specification exclusions statically guarantee that functions will only (possibly not) return and enable compiler optimization based on this knowledge

In fact, the exception specifications actually do something a little, but fundamentally different: they force the compiler to introduce additional runtime overheads in the form of implicit try / catch blocks around to ensure that the execution check function executes, the function executed by the function actually emits only the listed exceptions (possibly , no) if only the compiler can statically prove that the specification of the exception can never be violated, in which case the verification can be optimized far. Exception specifications can simultaneously enable and prevent compiler optimization (in addition to its own overhead described); for example, some compilers refuse built-in functions that have exception specifications.

Note that in some versions of Microsoft compilers (I'm not sure if this behavior has changed in later versions, but I don’t think so), throw() handled in a non-standard way. throw() equivalent to __declspec(nothrow) , which allows the compiler to assume that the function will not have an exception being thrown, and undefined behavior will occur if there is one.

C ++ 11 discounts the C ++ 98 style exception specification and introduces the noexcept keyword. The Bjarne Stroustup C ++ 11 FAQ says this:

If the declared noexcept function throws (so that the exception tries to escape, the noexcept function) the program terminates (by calling abort ()). The terminate () call cannot rely on objects in well-defined states (i.e. there is no guarantee that the destructors have been called, there is no guaranteed stack, and there is no way to resume the program as if there was a problem). This is intentional and makes nothing simpler than a simple, crude, and very efficient mechanism (much more efficient than the old dynamic cast () mechanism).

In C ++ 11, if an exception is thrown from a function marked as noexcept , the compiler is not required to unwind the stack at all. This provides some optimization options. Scott Myers discusses the new noexcept in his upcoming book, Effective Modern C ++.

+4
source

Source: https://habr.com/ru/post/1206366/


All Articles