Для чего нужен throw без аргументов в C++?

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

Ответ

Выражение throw; без аргументов используется только внутри обработчика catch для повторной генерации (rethrow) текущего перехваченного исключения. Это позволяет частично обработать исключение (например, залогировать, освободить ресурс) и затем передать его дальше по стеку вызовов для полноценной обработки.

Ключевое отличие от throw e;:

try {
    throw std::runtime_error("Original error");
} catch (std::exception& e) {
    e = std::runtime_error("Modified"); // Модифицируем ссылку на объект исключения
    // throw e; // Бросит КОПИЮ объекта типа std::exception (срезка!), с сообщением "Modified"
    throw;     // Бросит ИСХОДНОЕ исключение типа std::runtime_error, с сообщением "Original error"
}

Практический пример (логирование с последующей передачей):

void riskyOperation() {
    try {
        // ... код, который может бросить различные исключения
        someLowLevelFunction();
    }
    catch (...) {
        // Логируем факт ошибки на этом уровне, но не знаем, как её обработать
        std::cerr << "[ERROR] Exception in riskyOperation() at " << __LINE__ << std::endl;
        // Освобождаем критический ресурс, если нужно
        releaseResource();
        // Передаём исключение наверх, сохраняя его оригинальный тип и состояние
        throw;
    }
}

Важно: throw; вне блока catch приводит к неопределенному поведению (вызову std::terminate).