Warning: (to_be || !to_be) if always true! | OTUS
⚡ Подписка на курсы OTUS!
Интенсивная прокачка навыков для IT-специалистов!
Подробнее

Курсы

Программирование
Разработчик чат-ботов и приложений для виртуальных ассистентов
-15%
PHP Developer. Professional Алгоритмы и структуры данных Scala-разработчик PHP Developer. Basic C# Developer. Professional
-23%
C# ASP.NET Core разработчик Python Developer. Basic Python Developer. Professional Cloud Solution Architecture Специализация iOS
-25%
HTML/CSS Android Developer. Professional React.js Developer Unity Game Developer. Professional NoSQL Java Developer. Professional Highload Architect C++ Developer. Basic Web-разработчик на Python Unity Game Developer. Basic Интенсив «Оптимизация в Java» Супер-практикум по использованию и настройке GIT Symfony Framework Java Developer. Basic Супер-интенсив "Tarantool"
Инфраструктура
MongoDB
-30%
Разработчик чат-ботов и приложений для виртуальных ассистентов
-15%
Administrator Linux. Professional
-26%
Network engineer Administrator Linux. Advanced Специализация Administrator Linux
-25%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-27%
NoSQL Инфраструктурная платформа на основе Kubernetes Highload Architect Мониторинг и логирование: Zabbix, Prometheus, ELK Супер-практикум по использованию и настройке GIT Administrator Linux.Basic Экспресс-курс «IaC Ansible» Экспресс-курс по управлению миграциями (DBVC) Экспресс-курс "Версионирование и командная работа с помощью Git" Network engineer. Basic Основы Windows Server
Корпоративные курсы
Безопасность веб-приложений MongoDB
-30%
Разработчик чат-ботов и приложений для виртуальных ассистентов
-15%
Agile Project Manager Руководитель поддержки пользователей в IT
-10%
Промышленный ML на больших данных Cloud Solution Architecture Внедрение и работа в DevSecOps Spark Developer Reverse-Engineering IT-Recruiter Machine Learning. Professional Интенсив «Оптимизация в Java» Супер-практикум по использованию и настройке GIT Экcпресс-курс «ELK» Enterprise Architect Экспресс-курс «CI/CD или Непрерывная поставка с Docker и Kubernetes» Экспресс-курс «Введение в непрерывную поставку на базе Docker» Вебинар CERTIPORT
Специализации Курсы в разработке Подготовительные курсы Подписка
+7 499 938-92-02

Warning: (to_be || !to_be) if always true!

C++Deep_05.06_Site.png

Чем так хорош язык C++? Конечно, возможностью перегрузки операторов для своего класса! Ну ладно, разумеется, не только этим, но это классная возможность, разве нет? Давайте поговорим о перегрузке логических операторов, стоит ли это делать и чем это грозит (кроме непонятного кода в результате).

class SomeClass {
    public:
        bool operator&&(const SomeClass& other) {
            // тут сложный и запутанный код, например, копирования
            // объекта other в this
        }
};

Итак, дело сделано – у нашего класса переопределён оператор «&&». Если нам повезло, и наши коллеги не заблокировали такой код на review, то вполне можно им пользоваться всю оставшуюся карьеру. Мы получили клёвый способ копирования одного объекта в другой (чтобы враги не догадались, как работает наш код).

А что мы потеряли?

Потеряли мы оптимизацию логических вычислений и гарантию последовательного выполнения. О чем речь? Каждому хоть раз в жизни встречался вот такой код:

Type* a = prepareA(); // получили указатель на некий тип откуда-то
if (a && !a->isEmpty()) // пытаемся обработать 
    … 

Заметили?

Вообще говоря, код небезопасен, потому что, если в переменной «а» лежит пустой указатель, вызов isEmpty должен привести в лучшем случае к аварийному завершению программы. Однако, это работает, так как выполняется оптимизация логического выражения. Если a == nullptr, то вторая часть выражения просто не будет выполняться.

Таким образом, компилятор гарантирует, что, во-первых, первая часть выражения всегда будет исполнена первой (а мы помним, что в любом другом случае компилятор волен изменять порядок вычислений выражений), во-вторых, что вторая часть выражения выполнена не будет, если в этом не будет необходимости. Аналогичная логика работает и с оператором «||».

Согласно стандарту, как только компилятор встречает переопределённый оператор «&&» или «||», он волен больше не давать вышеобозначенной гарантии порядка вычисления выражений, а также обязан вычислить оба выражения независимо от из значений (делается это для того, чтобы выполнились все пост-эффекты вызовов таких операторов, даже если никаких пост-эффектов не закладывалось в реализации). Скорее всего, такое изменение поведения останется незаметным и будет безобидным, но помнить про него всё-таки желательно.

Дополнительный плюс – будет о чем поговорить за следующим чаепитием с коллегами.

Есть что добавить? Напишите в комментариях!

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
🔥 Выгодные предложения
Подборка курсов, которые можно приобрести по выгодной цене только до конца июля!