Исключения или коды ошибок
Вопрос
Когда вы используете исключения, а когда коды ошибок, std::optional или std::expected? Аргументируйте.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Исключения: ошибки, которые нельзя обработать на месте, конструкторы и операторы, редкие ситуации
Цена: дорогой бросок, невидимые пути выхода, требуется RAII
optional и expected: ожидаемые ошибки, явные в сигнатуре, дешёвые
Коды ошибок: C API, системные вызовы, -fno-exceptions
Единый стиль в проекте и на границах модулей
Что могут спросить следом
- Как сообщить об ошибке из конструктора без исключений?
- Что делать на границе C++ библиотеки и C API?
Разбор
Исключения использую для ошибок, которые нельзя разумно обработать там, где они возникли, и которые случаются редко: нехватка памяти, нарушение инварианта, невозможность создать объект. Это единственный нормальный способ сообщить об ошибке из конструктора или оператора. Плюс: ошибку нельзя молча проигнорировать, и она пролетает через много уровней без ручного проброса. Минусы: бросок дорогой, пути выхода не видны в коде, нужна дисциплина RAII. Для ожидаемых результатов вроде «запись не найдена» или «строка не распарсилась» возвращаю std::optional или std::expected<T, Error> из C++23: ошибка видна в сигнатуре, обработка явная, и нет цены раскрутки. Коды ошибок std::error_code остаются для системных вызовов, C API и проектов, собранных с -fno-exceptions. На границе с C исключения обязательно ловлю и превращаю в коды: если исключение вылетит в C-код, будет terminate или UB. Главное, чтобы стиль был единым внутри модуля.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.