Вопрос по c++, exception, c++11 – Когда я должен действительно использовать noexcept?

408

noexcept Ключевое слово может быть соответствующим образом применено ко многим сигнатурам функций, но я не уверен относительно того, когда мне следует рассмотреть возможность использования его на практике. Исходя из того, что я прочитал, добавление в последнюю минутуnoexcept кажется, решает некоторые важные проблемы, возникающие при броске конструкторов перемещения. Тем не менее, я все еще не могу дать удовлетворительные ответы на некоторые практические вопросы, которые побудили меня прочитать больше оnoexcept на первом месте.

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 ass). 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)?

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?

Error: User Rate Limit Exceededmove_if_nothrowError: User Rate Limit Exceeded R. Martinho Fernandes
Error: User Rate Limit Exceededgithub.com/isocpp/CppCoreGuidelines/blob/master/… moooeeeep
Error: User Rate Limit Exceededmove_if_noexcept. Nik-Lz

Ваш Ответ

8   ответов
14

Error: User Rate Limit Exceeded

Where termination is an acceptable response, an uncaught exception will achieve that because it turns into a call of terminate() (§13.5.2.5). Also, a noexcept specifier (§13.5.1.1) can make that desire explicit.

Successful fault-tolerant systems are multilevel. Each level copes with as many errors as it can without getting too contorted and leaves the rest to higher levels. Exceptions support that view. Furthermore, terminate() supports this view by providing an escape if the exception-handling mechanism itself is corrupted or if it has been incompletely used, thus leaving exceptions uncaught. Similarly, noexcept provides a simple escape for errors where trying to recover seems infeasible.

 double compute(double x) noexcept;   {       
     string s = "Courtney and Anya"; 
     vector<double> tmp(10);      
     // ...   
 }

The vector constructor may fail to acquire memory for its ten doubles and throw a std::bad_alloc. In that case, the program terminates. It terminates unconditionally by invoking std::terminate() (§30.4.1.3). It does not invoke destructors from calling functions. It is implementation-defined whether destructors from scopes between the throw and the noexcept (e.g., for s in compute()) are invoked. The program is just about to terminate, so we should not depend on any object anyway. By adding a noexcept specifier, we indicate that our code was not written to cope with a throw.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
11

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?

Error: User Rate Limit Exceeded

Error: User Rate Limit ExceededdesignError: User Rate Limit ExceededconstError: User Rate Limit ExceededandError: User Rate Limit Exceeded

Error: User Rate Limit ExceededforeverError: User Rate Limit Exceeded
Error: User Rate Limit Exceededa related Java question.
120

Error: User Rate Limit Exceededsemantics first.

Error: User Rate Limit Exceedednoexcept, noexcept(true)Error: User Rate Limit Exceedednoexcept(false)Error: User Rate Limit Exceeded

Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceededconstError: User Rate Limit Exceeded


Error: User Rate Limit Exceeded

Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededmove semantics.

Error: User Rate Limit ExceededhasError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededstd::terminateError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

  • immediately benefiting from noexcept even when dependencies do not use it already (backward compatibility)
  • allowing the specification of noexcept when calling functions that may theoretically throw but are not expected to for the given arguments
Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceededterminateError: User Rate Limit Exceededbad_allocError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded
Error: User Rate Limit ExceededonlyError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded
17
  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?

noexceptError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded

Error: User Rate Limit ExceedednoexceptError: User Rate Limit Exceedednoexcept.

Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded

  1. 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)?

Error: User Rate Limit Exceeded

  1. move operations (move assignment operator and move constructors)
  2. swap operations
  3. memory deallocators (operator delete, operator delete[])
  4. destructors (though these are implicitly noexcept(true) unless you make them noexcept(false))

Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededstd::vectorError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

  1. 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.

Error: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededthrow()Error: User Rate Limit Exceededthrow()Error: User Rate Limit Exceeded

Error: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded

Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceededstackoverflow.com/questions/88573/…
Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceededthrowError: User Rate Limit ExceededthrowError: User Rate Limit ExceededalmostError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededthrow_v2.
Error: User Rate Limit ExceededthrowError: User Rate Limit Exceeded
Error: User Rate Limit Exceededthrow()Error: User Rate Limit Exceedednothrow?
Error: User Rate Limit ExceededthrowsError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded
29

When can I realistically except 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.

Error: User Rate Limit Exceeded

noexceptError: User Rate Limit ExceededcompilerError: User Rate Limit ExceededconstError: User Rate Limit Exceeded

noexceptError: User Rate Limit ExceedednoexceptError: User Rate Limit ExceededyouError: User Rate Limit Exceeded

Error: User Rate Limit Exceededmove_if_noexceptError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededconst&Error: User Rate Limit Exceeded&&Error: User Rate Limit Exceeded

Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceededusefulError: User Rate Limit Exceededis_nothrow_constructibleError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

Error: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded
Error: User Rate Limit ExceededwillError: User Rate Limit ExceededcompilerError: User Rate Limit Exceeded
Error: User Rate Limit Exceededdifferent codepathError: User Rate Limit ExceededonlyError: User Rate Limit Exceededstd::vectorError: User Rate Limit ExceededdifferentError: User Rate Limit Exceeded
Error: User Rate Limit ExceededisError: User Rate Limit Exceeded
Error: User Rate Limit Exceededmove_if_noexceptError: User Rate Limit Exceededmove_if_noexceptError: User Rate Limit Exceeded
46

noexceptError: User Rate Limit Exceededstd::move_if_noexceptError: User Rate Limit Exceededstd::vectorError: User Rate Limit ExceededreserveError: User Rate Limit ExceededTError: User Rate Limit ExceededTError: User Rate Limit ExceededError: User Rate Limit Exceeded.

Error: User Rate Limit ExceedednoexceptError: User Rate Limit Exceedednoexcept added to them automaticallyError: User Rate Limit Exceeded
67

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

void foo(int x) {
    try {
        bar();
        x = 5;
        // other stuff which doesn't modify x, but might throw
    } catch(...) {
        // don't modify x
    }

    baz(x); // or other statement using x
}

Error: User Rate Limit ExceededbarError: User Rate Limit ExceedednoexceptError: User Rate Limit ExceededbarError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededbar()Error: User Rate Limit Exceeded

Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceedednothingError: User Rate Limit Exceededx = 5Error: User Rate Limit ExceededtryError: User Rate Limit Exceeded
Error: User Rate Limit ExceededthrowError: User Rate Limit ExceedednewError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededit must rely on the presence or absence of noexceptError: User Rate Limit Exceededthrow()Error: User Rate Limit Exceeded
155

Error: User Rate Limit Exceeded

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).

Error: User Rate Limit Exceeded

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.

Error: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded

Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceedednoexceptError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededstd::vectorError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededstd::terminateError: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededstd::terminateError: User Rate Limit ExceededthrowError: User Rate Limit Exceeded
Error: User Rate Limit Exceededstackoverflow.com/a/10128180/964135Error: User Rate Limit ExceedednoexceptError: User Rate Limit Exceeded
Error: User Rate Limit ExceedednoexceptError: User Rate Limit ExceededinterfaceError: User Rate Limit ExceededimplementationError: User Rate Limit Exceeded
Error: User Rate Limit ExceedednoexceptError: User Rate Limit Exceededstd::terminateError: User Rate Limit Exceeded

Похожие вопросы