Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

noexcept

Use case

Enable efficient std::vector reallocation by promising moves will not throw.

Explanation

noexcept promises a function will not throw exceptions. std::vector only uses move during reallocation if the move constructor is noexcept (otherwise it copies for exception safety). Always mark move operations noexcept when possible.

Code

#include <cstdint>
#include <cstring>
#include <iostream>
#include <vector>

struct CodeBuffer {
  uint8_t *data;
  size_t size;

  CodeBuffer(size_t n) : data(new uint8_t[n]), size(n) {
    std::cout << "Allocated " << n << " bytes.\n";
  }

  ~CodeBuffer() { delete[] data; }

  // If noexcept is not added to the move constructor,
  // copy is called.
  CodeBuffer(const CodeBuffer &other)
      : data(new uint8_t[other.size]), size(other.size) {
    std::memcpy(data, other.data, size);
    std::cout << "Copied.\n";
  }

  CodeBuffer(CodeBuffer &&other) noexcept : data(other.data), size(other.size) {
    other.data = nullptr;
    other.size = 0;
    std::cout << "Moved.\n";
  }

  CodeBuffer &operator=(const CodeBuffer &) = delete;
  CodeBuffer &operator=(CodeBuffer &&) = delete;
};

int main() {
  std::vector<CodeBuffer> buffers;
  buffers.emplace_back(100);
  buffers.emplace_back(200);
  buffers.emplace_back(300);
  return 0;
}

View on GitHub.

Output

$ ./src/c++11/build/noexcept
Allocated 100 bytes.
Allocated 200 bytes.
Moved.
Allocated 300 bytes.
Moved.
Moved.