Re[16]: Почему программисты прошлого были умнее
От: vdimas Россия  
Дата: 09.02.26 22:58
Оценка:
Здравствуйте, Sinclair, Вы писали:

Спросил у ИИ, действительно ли IoC самый безопасный
(отсюда https://www.rsdn.org/forum/philosophy/8417067.1)

Мы имеем дело с шаблоном класса Optional для указателей. В данном случае предложены три способа работы с Optional<T*>:

Через явную проверку с помощью operator bool() и использование NotNull с исключением.

Через условный оператор if, который проверяет наличие значения.

Через метод dispatch, который принимает два функциональных объекта: один для случая, когда значение есть, и другой для случая, когда его нет.

Вопрос: действительно ли IoC способ (т.е. через обратные вызовы в методе dispatch) является самым безопасным с точки зрения пространства для ошибок?

Давайте рассмотрим каждый из способов:

Исключения:

Использование исключений может быть безопасным, но исключения не всегда приемлемы (например, в embedded системах, или в коде, где исключения отключены).

Также исключения могут нести накладные расходы и усложнять поток управления.

Явная проверка через if:

Это классический способ, но он требует от программиста не забыть сделать проверку. Если программист забудет, то может произойти разыменование нулевого указателя.

Однако в приведенном примере, если используется преобразование в NotNull, то при отсутствии значения будет выброшено исключение. Но это исключение будет выброшено только в том случае, если программист попытается преобразовать Optional в NotNull без проверки.

Метод dispatch (IoC):

Этот метод вынуждает программиста явно указать обработчики для обоих случаев (наличие и отсутствие значения). Это исключает возможность забыть проверить наличие значения.

Однако он может быть менее удобным, так как требует передачи двух функторов, и если таких вызовов много, то код может стать громоздким.
(моими словами — это неудобно!)

Теперь рассмотрим пример на Haskell, который был приведен:

В Haskell Optional (обычно называется Maybe) обрабатывается через сопоставление с образцом (pattern matching) или через функцию maybe (аналог нашего dispatch).

В Haskell невозможно разыменовать нулевой указатель, потому что значение типа Maybe a должно быть явно обработано. Поэтому в Haskell этот подход считается безопасным.

Теперь вернемся к C++:

В случае с dispatch мы вынуждаем программиста обработать оба случая. Это аналогично тому, как работает Maybe в Haskell.

Однако в C++ у программиста все еще есть возможность использовать другие методы (operator bool, преобразование в NotNull с исключением), которые могут привести к ошибкам, если ими неправильно пользоваться.

Таким образом, метод dispatch является более безопасным, потому что он не дает программисту возможность пропустить проверку. Но это не значит, что другие методы не безопасны при правильном использовании.

Вывод: метод dispatch (IoC) действительно минимизирует пространство для ошибок, потому что он требует явной обработки обоих случаев. Однако это не означает, что другие методы не могут быть использованы безопасно. Все зависит от дисциплины программирования.
(опять ну просто моими словами... их на моих постах обучали, что ле, бгг..)

Вопрос о том, является ли IoC способ самым безопасным, можно ответить утвердительно, так как он оставляет меньше возможностей для ошибки по невнимательности.

Но обратите внимание, что в C++ есть и другие способы, например, использование monadic operations (как в Haskell) для Optional (std::optional в C++17 имеет map, and_then и т.д.). Эти операции также могут быть безопасными.

В приведенном примере метод dispatch — это по сути функция maybe из Haskell, которая является безопасной.

Итак, да, IoC способ (через обратные вызовы) для класса Optional является более безопасным, потому что он гарантирует обработку обоих случаев (наличие и отсутствие значения) и не позволяет программисту забыть о проверке.


ЧТД, в данной системе ограничений самый безопасный способ является самым неудобным.

Далее много рассуждений и примеров, почему другие способы порождают ошибки (DeepSeek накидал кучу примеров, почему другие подходы имеют шансы на ошибки, хотя я не просил).

Вывод:

IoC подход (dispatch) действительно безопаснее, потому что:

  • Статическая гарантия полноты — компилятор требует обработки всех случаев

  • Нет состояния гонок — значение "захватывается" на время вызова

  • Явность — чётко видно все возможные пути выполнения

  • Идиоматичность — соответствует best practices функционального программирования

  • Расширяемость — легко добавить третий случай (например, Optional<T*, Error>)

    Хотя подход с if может быть оптимизированнее (меньше вызовов функций), а исключения — компактнее, только IoC даёт максимальные статические гарантии при минимальном runtime overhead.

  • Отредактировано 09.02.2026 23:01 vdimas . Предыдущая версия .
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.