C++26 Contracts: пред- и постусловия прямо в сигнатуре функции

C++26 Contracts: Introduction to Preconditions and Postconditions

C++26 Contracts: пред- и постусловия прямо в сигнатуре функции

В C++26 появились контракты: pre и post позволяют указать требования к аргументам и обещания о результате прямо в объявлении функции. Это делает API самодокументируемым и даёт гибкие семантики проверки — ignore, observe, enforce, quick-enforce. Пока контракты поддерживает только GCC 16 с флагом -fcontracts. Внутри тела функции можно использовать contract_assert. Важно: контракты не предназначены для валидации ввода — для этого нужны обычные проверки.

Контрактные утверждения не должны использоваться для обработки ошибок и валидации ввода: если функция должна сообщать о некоторых событиях как об ошибках, это нужно делать стандартными управляющими конструкциями C++, а не контрактными утверждениями.
  1. cogman10

    Мне это не нравится.

    Я только за то, чтобы подписываться на контракт, если он может превратить ошибку времени выполнения в ошибку времени компиляции. Однако похоже, что это просто создаёт больше ошибок времени выполнения. В таком случае они выглядят не лучше, чем `assert`, за исключением того, что обещают действительно проверять (вероятно).

    В статье также указывается большая проблема: «Важно, что именно из-за этого аспекта Contracts контрактные утверждения не должны использоваться для обработки ошибок и валидации входных данных: если у функции есть контрактные требования сообщать о некоторых событиях как об ошибках, такая обработка должна выполняться стандартными управляющими операторами C++, которые не являются опциональными, и никогда — контрактными утверждениями».

    Такое размытое определение того, для чего должны использоваться контракты, почти наверняка приведёт к бардаку. Это не валидация входных данных, а валидация параметров... но на самом деле не валидация, а скорее проверки, которые выдают ошибку, но это не ошибки, которые мы производим.

  2. WalterBright

    Раньше я был большим поклонником контрактов и даже реализовал их в компиляторе Zortech C++ ещё в 90-х:

    https://www.digitalmars.com/ctg/contract.html

    Я также реализовал их в D. Но оказалось, что это не очень полезно.

  3. ZuLuuuuuu

    Это напоминает мне концепцию «Design by Contract» из языка программирования Eiffel:

    https://en.wikipedia.org/wiki/Design_by_contract

    https://www.eiffel.com/values/design-by-contract/introductio...

  4. Surac

    Что вообще хорошего в том, что мы не можем проверить входные данные? Удобный способ записать диапазоны параметров. И не более того.

  5. gavinray

    Случайный факт: много лет назад я написал плагин к компилятору GCC, чтобы добавить Contracts в C/C++, пока ждал, когда это войдёт в стандарт.

    https://gavinray97.github.io/blog/adding-invariant-to-cpp-de...

    Пост оказался полезнее как введение в написание плагинов для GCC, чем что-либо ещё, но по крайней мере мне было весело.

  6. tsukikage

    В статье не упоминаются случаи использования для оптимизации. Если кто-то уже знает навскидку и прежде чем я начну искать ответ, не является ли частью замысла то, чтобы они информировали этапы оптимизации, возможно, аналогично тому, чего можно достичь с помощью идиомы `if (!(some_condition)) { __builtin_unreachable(); }`?

  7. MetaverseClub

    Интересно, какие случаи использования они имеют в виду при разработке этого.

    Для утверждений времени выполнения и документации — да, это сработает, но и без контракта это работает, возможно, нормально.

    Для формальной верификации дизайн совершенно не тот.

  8. randyrand

    Может, только мне, но огромные сложные языки вроде C++ кажутся такими же непривлекательными, как и всегда.

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

Ещё за этот день

2026-10-15