В чем разница между выбросом исключения и вызовом std::abort в C++?

«В чем разница между выбросом исключения и вызовом std::abort в C++?» — вопрос из категории C++ Core, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

throw (выброс исключения) — это механизм контролируемой обработки ошибок. Он передает управление по стеку вызовов до первого подходящего блока catch. При этом корректно вызываются деструкторы всех локальных объектов в раскручиваемых фреймах стека (это называется stack unwinding и является основой идиомы RAII).

std::abort() — это функция из <cstdlib>, которая вызывает немедленное аварийное завершение программы (SIGABRT в POSIX). Деструкторы не вызываются, блоки catch не рассматриваются. Это жесткое завершение без какой-либо очистки.

Сравнение на практике:

class FileHandler {
    FILE* f;
public:
    FileHandler(const char* name) : f(fopen(name, "r")) {
        if (!f) throw std::runtime_error("Cannot open file"); // Восстановимая ошибка
    }
    ~FileHandler() { if (f) fclose(f); std::cout << "File closed.n"; }
    void read() { /* ... */ }
};

void riskyOperation() {
    FileHandler fh("data.txt"); // RAII-объект
    // ... какая-то работа ...
    if (criticalCondition) {
        // НЕПРАВИЛЬНО: вызовет утечку ресурса (файл не закроется).
        // std::abort();
        // ПРАВИЛЬНО: исключение вызовет деструктор fh.
        throw std::logic_error("Invalid state detected");
    }
}

int main() {
    try {
        riskyOperation();
    } catch (const std::exception& e) {
        std::cerr << "Ошибка перехвачена: " << e.what() << std::endl;
        // Программа продолжает работу, можно попробовать восстановиться.
        return 1;
    }
    return 0;
}

Когда что использовать:

  • Исключения (throw/catch) — для обработки ожидаемых, потенциально восстановимых ошибок (ошибки ввода/вывода, некорректные данные, сетевая недоступность). Это основной механизм обработки ошибок в современном C++.
  • std::abort() — только для фатальных, невосстановимых ошибок, когда продолжение работы программы бессмысленно или опасно (например, обнаружено критическое повреждение внутренних структур данных, нарушение инвариантов, которые не должны происходить никогда — assert по умолчанию вызывает abort).