[C++] How to Use noexcept | Explicitly Stating No Exceptions Are Thrown

目次

Introduction

In C++, functions potentially throw exceptions. However, there are many functions, such as getter functions or move constructors, that we know “will absolutely not throw an exception.”

The noexcept specifier, introduced in C++11, tells the compiler that a function does not throw exceptions by adding it after the function declaration. This allows the compiler to perform more aggressive optimizations, which can improve performance.

Also, noexcept serves as important documentation for programmers to clarify the specification of a function.

Prerequisite: What is C++11?

C++11 is a major update to the C++ language formalized in 2011. Since noexcept was introduced in C++11, you need a compiler that supports C++11 or later to use it.

How to Use noexcept

1. noexcept: Unconditionally Not Throwing Exceptions

When you add noexcept (or noexcept(true)), the function is marked as not throwing exceptions. If an exception is thrown from a function specified with noexcept, the program immediately calls std::terminate and ends abnormally.

#include <iostream>
#include <string>
#include <utility> // move

using namespace std;

class Widget {
private:
    string name_;

public:
    // This getter function does not contain processing that throws exceptions
    const string& getName() const noexcept {
        return name_;
    }

    // If you make move constructors and move assignment operators noexcept,
    // STL containers handle them more efficiently
    Widget(Widget&& other) noexcept {
        name_ = move(other.name_);
    }
};

Rule of Thumb: You should actively add noexcept to functions that generally should not throw exceptions, such as destructors, move constructors/move assignment operators, and swap functions.

2. noexcept(condition): Conditionally Not Throwing Exceptions

By putting a conditional expression evaluated at compile time inside the parentheses of noexcept, you can decide whether to enable the noexcept specification based on the condition.

This is very powerful, especially in template programming, when you want to inherit the noexcept property of a function belonging to a template argument type.

C++

class Resource {
public:
    void process() const { /* May throw exception */ }
};
class SafeResource {
public:
    void process() const noexcept { /* Does not throw exception */ }
};

// Template function
template <typename T>
void execute_process(const T& item) noexcept(noexcept(item.process())) {
    item.process();
}

int main() {
    // is_nothrow_invocable_v is a C++17 feature
    cout << boolalpha;
    cout << "execute_process<Resource> is noexcept? -> " 
         << noexcept(execute_process(Resource{})) << endl; // -> false

    cout << "execute_process<SafeResource> is noexcept? -> " 
         << noexcept(execute_process(SafeResource{})) << endl; // -> true

    return 0;
}

Explanation:

  • noexcept(item.process()): The noexcept operator returns a boolean value indicating the noexcept status of the expression passed as an argument.
    • If item is of type Resource: item.process() is not noexcept, so it returns false.
    • If item is of type SafeResource: item.process() is noexcept, so it returns true.
  • void execute_process(...) noexcept(...): The noexcept status of the execute_process function itself becomes linked to the noexcept status of the internal item.process() call.

Summary

In this article, I explained the C++11 noexcept specifier.

  • noexcept: Explicitly states that a function does not throw exceptions. This helps compiler optimization and may lead to performance improvements.
  • In principle, you should add noexcept to destructors and move operations.
  • noexcept(condition): Applies noexcept conditionally and propagates the noexcept status in templates.

By using noexcept appropriately, you provide important information about the function’s behavior to both the compiler and other programmers reading the code, allowing you to write safer and more efficient code.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次