В статье о повышении надёжности стандартной библиотеки мы видели, что многие требования библиотеки выражаются в виде «контрактов». Этот пост рассматривает контракты в C++26 и то, как их можно применять в собственном коде.
Обсуждение начинается с простого примера: функция возвращает значение из std::vector по заданному индексу. Традиционно требование корректности индекса обеспечивается с помощью assert в теле функции. У такого подхода есть недостатки. Требование находится в реализации, поэтому тот, кто читает только объявление, видит vector и индекс, но не связь между ними. Утверждения также управляются только макросом NDEBUG, который при его определении полностью удаляет проверку.
Контракты C++26, введённые через P2900, переносят требование в сигнатуру функции с помощью предложения pre(...), размещаемого после списка параметров. Это предусловие задаёт условие, которое ожидается выполненным при входе в функцию. То же требование может присутствовать и в объявлении, делая его видимым для каждого, кто читает API. Контракты предлагают несколько семантик вычисления: игнорирование проверки, сообщение о нарушении с продолжением работы или завершение программы. Какие из них доступны и как они выбираются, определяет реализация компилятора.
Контракты также различают то, что вызывающая сторона должна предоставить, и то, что функция обещает вернуть. Постусловия, вводимые с помощью post, выражают эти обещания без необходимости ручных проверок перед каждым оператором return. Поэтому контракты полезны для документирования API даже тогда, когда проверки во время выполнения отключены.
Статья завершается полным примером предусловия и рассматривает дополнительные темы: постусловия, размещение контрактов в объявлениях и определениях, опции компилятора и детали, которые могут удивить разработчиков.
Источник: Hacker News · Сводку подготовил HeadlinesBriefing