C++26 Contracts: Introduction to Preconditions and Postconditions
24 points by ibobev 2 hours ago | 14 comments

randyrand 29 minutes ago
Maybe just me, but huge complicated languages like C++ seem as unappealing as ever.

If I’m going to write code by hand, the requirement for a beautiful pleasant language is bigger than ever.

reply
ahartmetz 23 minutes ago
On the one hand, almost everyone (including C++ fans) agrees that the language is too big. On the other hand, comtracts just formalize an existing and useful concept.
reply
nananana9 12 minutes ago
Where do I put these?

If I put them in the header, I have to include half the world because I can't forward declare `Foo foo` argument if I want to check `foo.size() > 3` or similar in a pre/post-condition. This is a non-starter, keeping headers lean is the only way to not end up with 1 hour compiles.

If I put them in the cpp, they lose their only advantage over asserts - that they also double as documentation in the headers.

Did we add 50 pages to the standard for a slightly fancier assert? I feel like this could've been one builtin and a footnote:

contract_assert(expr) - if expr evaluates to false, the behavior of the program is undefined. Implementations are encouraged to emit a runtime check for this in debug builds, or a compiler error in cases where they can statically determine, that the assert will fail.

reply
preommr 28 minutes ago
I am very bullish on constraints based programming like this.

The main problem is code organization and syntax. Tacking stuff like this onto fuction declarations is too basic.

Ideally, I think we need better constructs, e.g. dettached constraints like to the function declaration. You can define constraints separately, in the same namespace or w/e, add notes, comments, etc. and the function declaration can be used with intellisense to jump to the constraint. You could even tag the defintions.

In modern AI-based workflows, the agent can pull up an explanation on the function, and point directly to the constraints, with strong confidence esp. if it's got explicit metadata.

reply
klibertp 4 minutes ago
Take a look at Racket (or Rhombus if allergic to parens). Support for contracts there is stellar and provides everything you mentioned. You can use `define/contract` for inline contracts, or you can attach contracts when exporting names from a module using `contract-out` declaration. Contracts are first-class, can be defined separately and attached wherever you want (importantly, this includes values (structs, classes) as well as functions). There are higher-order contracts that generate new contracts from existing ones. There's support for both static and dynamic metadata for almost all kinds of entities in code (ie. both the syntax and the semantic entity it produces can be annotated with anything). I wouldn't recommend using Racket/Rhombus in production, but it's a great preview of what might become commonplace in a decade or two :)
reply
ZuLuuuuuu 26 minutes ago
This reminds me the "Design by Contract" concept from Eiffel programming language:

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

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

reply
gavinray 20 minutes ago
If you enjoy this style of programming, I wrote a bit on why contracts and capabilities (ie "allocates memory", "performs i/o") are going to become essential for LLM generated code:

https://gavinray97.github.io/blog/design-by-contract-and-eff...

reply
bluGill 33 minutes ago
I'm looking forward to seeing where these go in the future. Can solvers prove my code correct (at least in some trivial cases)? What should happen in a unit test (sometimes I want to test that my program handles out of range values, sometimes it is expensive top check and so I put the contract in to avoid the check at runtime...) Can/should the optimizer account for contracts (same question as unit tests).
reply
klibertp 15 minutes ago
See the papers "Soft Contract Verification" and "Soft Contract Verification for Higher-Order Stateful Programs" (Nguyễn et al.) In general, there's a lot of academic work on the topic coming from the Racket community.

In short: yes, some classes of contracts can be statically proven. Not all of them, and it depends on the language's semantics, so it's probably not easy to retrofit into C++. But there's work being done on unifying types and contracts, moving back and forth between static proof and dynamic enforcement, and it's all pretty interesting. Proving contracts statically eliminates runtime overhead; generating contracts from types makes it possible for a gradually typed language to be sound.

reply
literallyshared 33 minutes ago
I can see the appeal of having 'code as documentation' in header files, but personally I find any type of runtime asserts to be too heavy handed. Graceful error handling, in my opinion, is always preferable. This type of functionality is what is continuing to drive me away from C++. If your preconditions and postconditions matter, document them in a comment block.
reply
bluGill 11 minutes ago
Graceful handling is a trade off. Sometimes the check is expensive, if everybody normally does it right you don't want to check (particularly in a tight loop), but you don't want to lose this. I work in embedded, in production our CPUs are not powerful enough to risk all those runtime checks, but I want to turn them on when I work on my workstation - in hopes that if there is a problem we catch it.

Contacts are also a guaranteed syntax. Runtime checks provide no way for tools to know if the condition is expected to never happen - this is a bug; vs this is a normal user error we need to check for. A contract means theorem provers can find code paths where a bug could happen - of course we don't have theorem provers for C++, but this is seen as a requirement to get them.

reply
ahartmetz 26 minutes ago
You can set a "contract evaluation semantic" for contracts. One of them is "observe", which only prints a message on contract violations. With "ignore", nothing at all happens.
reply
hsaliak 18 minutes ago
id' normally hate this but with agents this is awesome
reply
beached_whale 4 minutes ago
An anthropic employee did a talk earlier this year or last and i think it was said that yeah, they eat it up. Tools to find errors because it is visible is great
reply
chelseahermes 29 minutes ago
[flagged]
reply