Date: Tue, 18 Aug 2026 22:30:17 +0100
On 16/08/2026 00:41, Peter Bindels wrote:
> Hi Jonathan,
>
> On Sat, Aug 15, 2026 at 11:31 PM Jonathan Grant via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
>
> Hello
>
> Sharing my notes and feedback after reading.
>
> I read P4334R0:
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4334r0.pdf <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4334r0.pdf>
>
> Is it possible to review/reconsider P2900 until this approach for Contracts have had more time for field use?
>
> BTW, there is also a broken (404) link in P4334R0 to D4324R0:
> https://isocpp.org/files/papers/D4324R0.html <https://isocpp.org/files/papers/D4324R0.html>
>
> Could someone point me to the paper?
>
> I read P4332R0 too
> https://isocpp.org/files/papers/P4332R0.html <https://isocpp.org/files/papers/P4332R0.html>
>
> I have some concerns about C++ Contracts.
>
>
> Please do try it out. It's available on any machine that can install GCC16. There is also a Clang fork that implements most of it, that is not merged to mainline but that is being actively worked on in two directions - one to extend it, and one to merge it to main.
Many thanks for your reply.
Yes I have tried it out.
>
> One of the papers says it's not implemented - I don't understand how they cannot see GCC16 existing since March, in a paper written in August. It makes you doubt the other statements in the paper, even though there are some valid concerns in there.
>
> With regards to actual use of it, many people I talk to are indeed trying it out, and finding it very useful. Quoting from two people's unprompted statements:
>
>> Once you set up the initial callback function the syntax around it seems to be really quite simple
>
The callbacks are one of the concerns I had. My thoughts are, once P2900 is standardized, it is difficult to revise/simplify what is in use. Maybe the other C++ Proposal, Profiles would be better? That's standardizing a subset.
>> They really are. I'm finding they're bloody useful.
>
> I have been looking into the quality of implementation, and there are a few bugfixes pending on GCC still.
>
> I have also looked at what constification would mean for an actual codebase in P3268, and tried it in my personal codebase of about 50kloc, where it found one ICE in both the GCC and Clang implementations (Clang is unmerged), and about 10 bugs in my code. Not a widespread rollout, true, but experience nevertheless. That specific ICE was fixed this week for a future release.
>
> We can postpone contracts until after more experience is gained, but that does cause issues for further development on contracts, and on anything else that tries to rely on their specification for runtime checks and failure handling. Nothing insurmountable, but unpleasant nonetheless.
>
> At a conceptual level, contracts are Hoare logic: precondition, command, postcondition. That underlying idea is simple, whereas the C++ Contracts specification appears far more complicated.
>
> If there was scope to consider a simpler approach, which places emphasis on compile-time checks that would be very useful for functional safety. Runtime checks are risky.
>
> Relying upon a contract violation being detected at runtime has issues. The violation may occur only after deployment, and runtime checks may potentially be marked 'ignore'. The contract-violation handler also introduces a runtime path which cannot necessarily be shown at compile time to be unreachable. For functional safety, it's an unknown, if it will be called.
>
> This is relevant to functional-safety software, where it is important to demonstrate that a violation handler cannot be called, rather than relying on it to catch a violation at runtime. Which leaves the question what to do, when it is called. Hard to prove, if the symbol is present and linked to.
>
> My own proposal, compile_assert(), P4021, explores a different approach:
> https://wg21.link/P4021 <https://wg21.link/P4021>
>
> compile_assert() operates at compile time and deliberately has a very small implementation model. Naturally, it can only verify properties which the compiler is able to determine at compile time.
>
> As an experiment, I have implemented contract-like checks in terms of compile_assert().
> https://github.com/jonnygrant/compile_assert/blob/main/testsuite/main28_a.cpp <https://github.com/jonnygrant/compile_assert/blob/main/testsuite/main28_a.cpp>
>
>
> compile_assert, if I understand it correctly, is identical to contracts in P2900 when set up to have a C++ library that does not implement its violation handler function. Your program will link if and only if it could be proven during compilation. That already works like that - in fact, I at first didn't notice I had forgotten to switch over to my experimental libc++ until it failed to link after adding a few contracts. The first few in the places they were called were always true and didn't emit a symbol to link to in the first place.
>
compile_assert() is eloquent, just a few lines of code, it uses the compiler's internal knowledge and exposes it to the programmer, compile_assert isn't present in any compiled code. The sample works in GCC since version 4.5.3 (2011). The Linux Kernel has had similar for over a decade. So my proposal would standardize existing use.
Matt Borland's SafeNumbers uses compile_assert for Compile Time Pre-Condition checks
https://develop.safe-numbers.cpp.al/compile_time_checks.html
I've read P2900 C++ Contracts and it's very different. P2900 is a very large specification and at runtime.
It's a functional safety concern to have runtime behaviour in callbacks, and ignore. observe - continuing means the issue is missed, enforce - very difficult to recover from such a callback - far better to identify such bugs at compile-time. quick-enforce, is just std::terminate()?
On top of the simple statement form of compile_assert() it's possible to implement more advanced Rust style ownership models, optionality etc. P2900 does look very large for what could can be achieved at compile-time in a few lines. Compile-time Contracts I put in one of the testsuite files was 3 lines of code on top of compile_assert().
Maybe with your knowledge and experience of P2900 C++ Contracts you'd like to see the compile_assert example of contracts? It's here on godbolt, see it find the bugs at compile time on lines 78 and 79.
https://godbolt.org/z/9P731ozzz
> With regards to proving things at compile time, the current definition of contracts is enough for simple assertions. Anything that is too complicated (lamdbas, usually) or that passes through an opaque interface that the compiler cannot see into, cannot be optimized. In particular, a sequence f(g(x)) where both g(x) has a postcondition r:p(rv) and f(r) has a precondition p(r), cannot forward the result of a postcondition on g(x) to f, as there is no way to explain that evaluating p with the same argument twice will do the same thing twice. For repeated checks on a precondition we have taken that allowance into the standard, but for this specific situation we'd need something like [[reproducible]] or [[unsequenced]] as in C.
>
Do you mean though abstract base classes with virtual functions?
compile_assert works through APIs, but I have not tried opaque interfaces. It might work.
> Beyond that, I know that multiple different groups of people are looking into what specifically we can do with contracts as specified, and what we'd need to change or add. So far the results seem to be that it works well enough, but that with minor tweaks we can make it more powerful. A hypothetical [[mustprove]] attribute could exist in a compiler, requesting it to fail the build if it cannot prove a functions' calls' pre-contracts, and its postcontract, based on its own pre-contracts and its calls' postcontracts. Basically, asking the compiler to do the Hoare propagation and seeing if it connects, at a semantic level that would need to be done early on in a compiler. Given such information, depending on build modes, a compiler can just remove all checks in that function, as there's no way they don't hold. Will never be able to do all code - but if it can do 95% of the code, I'll happily review or rewrite the remaining 5%. Think of it like a borrow checker for the guarantees
> that brings, except functional safety (and whatever memory safety was expressed in contracts).
>
I implemented an Ownership class borrow checker with a few lines of code using compile_assert(), at compile-time.
Sir Tony Hoare gave a good presentation, may I ask if you have seen this one?
The 1980 ACM Turing Award Lecture
The Emperor's Old Clothes
Tony Hoare wrote about PL/1 and ADA, how they got bigger, more complicated. Tony Hoare spoke about simplification of programming languages, taking a subset when referring to ALGOL, ADA and other projects from his career.
I'll share a quote:
"I conclude that there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies."
>
> But let's first see what happens with the C++26 DIS. If you want to form an opinion on how well it works, try it out - godbolt, local install - and form your own opinion. And if you'd like it to have more features maybe consider not voting against for that reason. That's not going to get you more features - it's only going to cause more turbulence and delay.
>
Tony Hoare was keen on subsets, simple features, I feel similar, my preference I rather it was far smaller and at compile-time, without any runtime behaviour. A contract is a compile-time proof obligation, it should not have runtime behaviour. Tony Hoare suggested to resist features whose complexity exceeds our ability to understand their consequences. ie my objection is not against Hoare Logic Contracts in C++; it's an objection to making the technological mechanics of expressing Contracts a runtime model.
May I ask your viewpoint - would you consider if the design of C++ Contracts were simpler, compile-time only, without any runtime behaviour/callbacks would that be more useful for programmers?
> Regards,
> Peter
Thank you again for your reply.
Best regards
Jonathan
> Hi Jonathan,
>
> On Sat, Aug 15, 2026 at 11:31 PM Jonathan Grant via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
>
> Hello
>
> Sharing my notes and feedback after reading.
>
> I read P4334R0:
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4334r0.pdf <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4334r0.pdf>
>
> Is it possible to review/reconsider P2900 until this approach for Contracts have had more time for field use?
>
> BTW, there is also a broken (404) link in P4334R0 to D4324R0:
> https://isocpp.org/files/papers/D4324R0.html <https://isocpp.org/files/papers/D4324R0.html>
>
> Could someone point me to the paper?
>
> I read P4332R0 too
> https://isocpp.org/files/papers/P4332R0.html <https://isocpp.org/files/papers/P4332R0.html>
>
> I have some concerns about C++ Contracts.
>
>
> Please do try it out. It's available on any machine that can install GCC16. There is also a Clang fork that implements most of it, that is not merged to mainline but that is being actively worked on in two directions - one to extend it, and one to merge it to main.
Many thanks for your reply.
Yes I have tried it out.
>
> One of the papers says it's not implemented - I don't understand how they cannot see GCC16 existing since March, in a paper written in August. It makes you doubt the other statements in the paper, even though there are some valid concerns in there.
>
> With regards to actual use of it, many people I talk to are indeed trying it out, and finding it very useful. Quoting from two people's unprompted statements:
>
>> Once you set up the initial callback function the syntax around it seems to be really quite simple
>
The callbacks are one of the concerns I had. My thoughts are, once P2900 is standardized, it is difficult to revise/simplify what is in use. Maybe the other C++ Proposal, Profiles would be better? That's standardizing a subset.
>> They really are. I'm finding they're bloody useful.
>
> I have been looking into the quality of implementation, and there are a few bugfixes pending on GCC still.
>
> I have also looked at what constification would mean for an actual codebase in P3268, and tried it in my personal codebase of about 50kloc, where it found one ICE in both the GCC and Clang implementations (Clang is unmerged), and about 10 bugs in my code. Not a widespread rollout, true, but experience nevertheless. That specific ICE was fixed this week for a future release.
>
> We can postpone contracts until after more experience is gained, but that does cause issues for further development on contracts, and on anything else that tries to rely on their specification for runtime checks and failure handling. Nothing insurmountable, but unpleasant nonetheless.
>
> At a conceptual level, contracts are Hoare logic: precondition, command, postcondition. That underlying idea is simple, whereas the C++ Contracts specification appears far more complicated.
>
> If there was scope to consider a simpler approach, which places emphasis on compile-time checks that would be very useful for functional safety. Runtime checks are risky.
>
> Relying upon a contract violation being detected at runtime has issues. The violation may occur only after deployment, and runtime checks may potentially be marked 'ignore'. The contract-violation handler also introduces a runtime path which cannot necessarily be shown at compile time to be unreachable. For functional safety, it's an unknown, if it will be called.
>
> This is relevant to functional-safety software, where it is important to demonstrate that a violation handler cannot be called, rather than relying on it to catch a violation at runtime. Which leaves the question what to do, when it is called. Hard to prove, if the symbol is present and linked to.
>
> My own proposal, compile_assert(), P4021, explores a different approach:
> https://wg21.link/P4021 <https://wg21.link/P4021>
>
> compile_assert() operates at compile time and deliberately has a very small implementation model. Naturally, it can only verify properties which the compiler is able to determine at compile time.
>
> As an experiment, I have implemented contract-like checks in terms of compile_assert().
> https://github.com/jonnygrant/compile_assert/blob/main/testsuite/main28_a.cpp <https://github.com/jonnygrant/compile_assert/blob/main/testsuite/main28_a.cpp>
>
>
> compile_assert, if I understand it correctly, is identical to contracts in P2900 when set up to have a C++ library that does not implement its violation handler function. Your program will link if and only if it could be proven during compilation. That already works like that - in fact, I at first didn't notice I had forgotten to switch over to my experimental libc++ until it failed to link after adding a few contracts. The first few in the places they were called were always true and didn't emit a symbol to link to in the first place.
>
compile_assert() is eloquent, just a few lines of code, it uses the compiler's internal knowledge and exposes it to the programmer, compile_assert isn't present in any compiled code. The sample works in GCC since version 4.5.3 (2011). The Linux Kernel has had similar for over a decade. So my proposal would standardize existing use.
Matt Borland's SafeNumbers uses compile_assert for Compile Time Pre-Condition checks
https://develop.safe-numbers.cpp.al/compile_time_checks.html
I've read P2900 C++ Contracts and it's very different. P2900 is a very large specification and at runtime.
It's a functional safety concern to have runtime behaviour in callbacks, and ignore. observe - continuing means the issue is missed, enforce - very difficult to recover from such a callback - far better to identify such bugs at compile-time. quick-enforce, is just std::terminate()?
On top of the simple statement form of compile_assert() it's possible to implement more advanced Rust style ownership models, optionality etc. P2900 does look very large for what could can be achieved at compile-time in a few lines. Compile-time Contracts I put in one of the testsuite files was 3 lines of code on top of compile_assert().
Maybe with your knowledge and experience of P2900 C++ Contracts you'd like to see the compile_assert example of contracts? It's here on godbolt, see it find the bugs at compile time on lines 78 and 79.
https://godbolt.org/z/9P731ozzz
> With regards to proving things at compile time, the current definition of contracts is enough for simple assertions. Anything that is too complicated (lamdbas, usually) or that passes through an opaque interface that the compiler cannot see into, cannot be optimized. In particular, a sequence f(g(x)) where both g(x) has a postcondition r:p(rv) and f(r) has a precondition p(r), cannot forward the result of a postcondition on g(x) to f, as there is no way to explain that evaluating p with the same argument twice will do the same thing twice. For repeated checks on a precondition we have taken that allowance into the standard, but for this specific situation we'd need something like [[reproducible]] or [[unsequenced]] as in C.
>
Do you mean though abstract base classes with virtual functions?
compile_assert works through APIs, but I have not tried opaque interfaces. It might work.
> Beyond that, I know that multiple different groups of people are looking into what specifically we can do with contracts as specified, and what we'd need to change or add. So far the results seem to be that it works well enough, but that with minor tweaks we can make it more powerful. A hypothetical [[mustprove]] attribute could exist in a compiler, requesting it to fail the build if it cannot prove a functions' calls' pre-contracts, and its postcontract, based on its own pre-contracts and its calls' postcontracts. Basically, asking the compiler to do the Hoare propagation and seeing if it connects, at a semantic level that would need to be done early on in a compiler. Given such information, depending on build modes, a compiler can just remove all checks in that function, as there's no way they don't hold. Will never be able to do all code - but if it can do 95% of the code, I'll happily review or rewrite the remaining 5%. Think of it like a borrow checker for the guarantees
> that brings, except functional safety (and whatever memory safety was expressed in contracts).
>
I implemented an Ownership class borrow checker with a few lines of code using compile_assert(), at compile-time.
Sir Tony Hoare gave a good presentation, may I ask if you have seen this one?
The 1980 ACM Turing Award Lecture
The Emperor's Old Clothes
Tony Hoare wrote about PL/1 and ADA, how they got bigger, more complicated. Tony Hoare spoke about simplification of programming languages, taking a subset when referring to ALGOL, ADA and other projects from his career.
I'll share a quote:
"I conclude that there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies."
>
> But let's first see what happens with the C++26 DIS. If you want to form an opinion on how well it works, try it out - godbolt, local install - and form your own opinion. And if you'd like it to have more features maybe consider not voting against for that reason. That's not going to get you more features - it's only going to cause more turbulence and delay.
>
Tony Hoare was keen on subsets, simple features, I feel similar, my preference I rather it was far smaller and at compile-time, without any runtime behaviour. A contract is a compile-time proof obligation, it should not have runtime behaviour. Tony Hoare suggested to resist features whose complexity exceeds our ability to understand their consequences. ie my objection is not against Hoare Logic Contracts in C++; it's an objection to making the technological mechanics of expressing Contracts a runtime model.
May I ask your viewpoint - would you consider if the design of C++ Contracts were simpler, compile-time only, without any runtime behaviour/callbacks would that be more useful for programmers?
> Regards,
> Peter
Thank you again for your reply.
Best regards
Jonathan
Received on 2026-08-18 21:30:25
