Что такое гарантии безопасности исключений (exception safety) в C++?

«Что такое гарантии безопасности исключений (exception safety) в C++?» — вопрос из категории C++ Core, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Гарантии безопасности исключений (exception safety) — это свойства функции или метода, описывающие, как её поведение влияет на состояние программы при возникновении исключения. Выделяют три основные гарантии (от слабой к сильной):

  1. Базовая гарантия (Basic Guarantee): При выбросе любого исключения программа остаётся в валидном состоянии. Не происходит утечек ресурсов, инварианты объектов сохраняются, но состояние может измениться (например, объект может остаться в каком-то промежуточном, но корректном состоянии).

  2. Строгая гарантия (Strong Guarantee): Операция обладает транзакционной семантикой. Если операция завершается исключением, состояние программы остаётся точно таким же, как и до её начала. Это часто реализуется через идиому "copy-and-swap".

  3. Гарантия отсутствия исключений (No-throw Guarantee): Операция никогда не генерирует исключений. Это критически важно для деструкторов и функций освобождения ресурсов (например, operator delete).

Пример реализации строгой гарантии с помощью "copy-and-swap":

class String {
    char* data;
    size_t size;
public:
    void append(const char* str) {
        // 1. Создаём копию текущего состояния
        String temp(*this);
        // 2. Модифицируем копию (если здесь выбросится исключение, *this не пострадает)
        temp.internalAppend(str);
        // 3. Атомарно меняем состояние текущего объекта на новое
        swap(temp); // swap обычно noexcept
    }
    void swap(String& other) noexcept {
        std::swap(data, other.data);
        std::swap(size, other.size);
    }
    // ...
};

Практическое правило: Деструкторы, операции swap, move должны обеспечивать no-throw guarantee. Ключевые операции следует стремиться делать либо строго безопасными, либо, как минимум, обеспечивающими базовую гарантию.