How to use noexcept in C++ or How does it work?

Ankit Acharya picture Ankit Acharya · Oct 19, 2015 · Viewed 11.9k times · Source

I am unable to understand the use & purpose of the noexcept keyword in C++11/14. I understand that it is a signature for a function that does not emit exceptions. But does it really work?

Look at this code below :

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void seev (vector<int> &v) noexcept;
void seev (vector<int> &v) noexcept
{
    for (int i=0;i<10;++i)
    {
        cout<<v.at(i)<<' ';
    }
}
int main()
{
    vector<int> v {1,2,3,4,5};
    seev(v);
    return 0;
}

The above code will surely throw an out_of_range exception. So the use of noexcept here is useless, or is it?

My queries are :

  1. How does noexcept work?

  2. How is it used?

  3. What throw() wasn't able to do that noexcept could?

Answer

Validus Oculus picture Validus Oculus · Oct 19, 2015

A noexcept specification on a function is merely a method for a programmer to inform the compiler whether or not a function should throw exceptions.

The compiler can use this information to enable certain optimizations on non-throwing functions as well as enable the noexcept operator, which can check at compile time if a particular expression is declared to throw any exceptions.

For example, containers such as std::vector will move their elements if the elements' move constructor is noexcept, and copy otherwise (unless the copy constructor is not accessible, but a potentially throwing move constructor is, in which case the strong exception guarantee is waived).

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

For more details, please visit below websites

Edit: Sample source code to illustrate above points.

// whether foo is declared noexcept depends on if the expression
// T() will throw any exceptions, check in compile time
template <class T>
void foo() noexcept(noexcept(T())) {     
}

void bar() noexcept(true) {    
}

void baz() noexcept {
    throw 42;     
}  // noexcept is the same as noexcept(true)

int main() 
{
    foo<int>();  // noexcept(noexcept(int())) => noexcept(true), so this is fine

    bar();  // fine
    baz();  // compiles, but at runtime this calls std::terminate
}