А является ли эта непредсказуемость (надо сказать, очень условная) действительно проблемой?
Почему оптимизация хранения коротких строк в std::string к примеру не является такой же проблемой?
std::expected размером больше чем примитивный тип и скорее всего по конвенции вызова не влезет в регистр возврата значения и поедет через стек, а это значит что для успешного пути тоже создаст дополнительные накладные расходы.
Разница в том, что код ошибки проигнорировать можно, а исключение - нельзя.
Вернее, можно проигнорировать и то и другое локально, но исключение полезет вверх по стеку и его придётся обработать выше. Код возврата проигнорировать легче (промолчим про лист подорожника по имени [[nodiscard]]).
Далее, если произошла ошибочная ситуация, то не факт что её можно корректно парировать ровно в месте непосредственного вызова. Нередко корректная возможна лишь на несколько фреймов выше. И это прекрасно понимают в ООП-языках, но почему-то борются с этим в С++...
Под полиморфным поведением конкретно здесь я понимаю полиморфизм в стиле ООП.
Если у вас есть открытая иерархия типов с виртуальными методами, то невозможно в сигнатуре метода в базовом типе указать все возможные отказы, которые могут возникнуть в любом (будущем) потомке. Но эту проблему как раз решают исключения.
Вторая проблема: если какой-то из вложенных вызовов может вернуть ошибку, которую нужно будет проанализировать, то эта деталь реализации в отсутствии исключений просочится в сигнатуры всех промежуточных методов. Исключения делает сигнатуры методов чище, но контракты становятся неявными.
На самом деле в C# ломающих изменений было, пожалуй, не больше чем в C++ (я сходу вспоминаю лишь два граничных случая, которые никогда не были в проде в исходном их виде).
А концептуальных расширений - примерно столько же.
У Вас что, исключения используются для Control Flow, что исключения на каждом шагу?
Давайте сразу оговорим, что это с точки зрения задач, с которыми Вы работаете и здесь неявно подразумеваете.
Это не обязательно справедливо для любого класса задач.
А является ли эта непредсказуемость (надо сказать, очень условная) действительно проблемой?
Почему оптимизация хранения коротких строк в std::string к примеру не является такой же проблемой?
std::expected размером больше чем примитивный тип и скорее всего по конвенции вызова не влезет в регистр возврата значения и поедет через стек, а это значит что для успешного пути тоже создаст дополнительные накладные расходы.
Накладных расходов меньше на пути, когда ошибка возникает. На нормальном пути - больше.
А ещё ментальная сложность при поддержке этого дела и при отсутствии дисциплины - возникновение желания что-нибудь "неважное" отрезать.
Получилось ничто иное, как базовый класс Exception, только свой. А зачем?
Разница в том, что код ошибки проигнорировать можно, а исключение - нельзя.
Вернее, можно проигнорировать и то и другое локально, но исключение полезет вверх по стеку и его придётся обработать выше. Код возврата проигнорировать легче (промолчим про лист подорожника по имени [[nodiscard]]).
Далее, если произошла ошибочная ситуация, то не факт что её можно корректно парировать ровно в месте непосредственного вызова. Нередко корректная возможна лишь на несколько фреймов выше. И это прекрасно понимают в ООП-языках, но почему-то борются с этим в С++...
Если Вы делаете открытую систему, пригодную для расширения, то скорее всего коды ошибок создадут больше проблем, чем решат.
Под полиморфным поведением конкретно здесь я понимаю полиморфизм в стиле ООП.
Если у вас есть открытая иерархия типов с виртуальными методами, то невозможно в сигнатуре метода в базовом типе указать все возможные отказы, которые могут возникнуть в любом (будущем) потомке. Но эту проблему как раз решают исключения.
Вторая проблема: если какой-то из вложенных вызовов может вернуть ошибку, которую нужно будет проанализировать, то эта деталь реализации в отсутствии исключений просочится в сигнатуры всех промежуточных методов. Исключения делает сигнатуры методов чище, но контракты становятся неявными.
PS: В Java вон Checked exceptions где сейчас?..
В мире .NET-а в них сходили как минимум дважды (client profile, netstandard), и, к счастью, закопали.
Я так понимаю над обработкой ошибок вы особо не думали, и полиморфное поведение не используете.
На самом деле в C# ломающих изменений было, пожалуй, не больше чем в C++ (я сходу вспоминаю лишь два граничных случая, которые никогда не были в проде в исходном их виде).
А концептуальных расширений - примерно столько же.
Вы на 2 порядка ошиблись в расчёте
Речь про другое: если сообщение не нужно на текущем уровне логирования, то вообще не надо его формировать, включая форматирование и прочее.
Вопрос влияния на производительность при генерации сообщений ниже требуемого уровня логирования оставляем в стороне?
... если ни один из целевых методов не поднял исключения
Ложное утверждение.
Депутат будет тупить, как и раньше - привычное явление.
Пост, где ссылка в телеграм, где ссылка в бот, который...
Так и до смерти Кощея не далеко.
И сколько эти эксперты обходятся в деньгах на одного взятого кандидата?
Некросетки тоже работают за еду (электроэнергию).