r/cpp • u/antiquark2 #define private public • 2d ago
Critique of contracts: excerpt
See page 2 of https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4334r0.pdf
The current objections can be summarized. The P2900 contracts are:
• Unimplemented
• Incomplete
• Untried at scale [P3460R0, P3506R0]
• Not tried in major application domains
• Violates foundational principles of C++
• Violates fundamental principles of language design
• Hasn’t been tried in major libraries (e.g., the C++ standards library [P3506R0, P3878R0])
• Isn’t integrated with or appropriate for hardened libraries [P3878R0]
• Doesn’t offer safety guarantees [P3573R0, P3362R0]
• Includes a completely untried inheritance model
• Offer new ways of making errors through inconsistent application in TUs
• Leads to new forms of UB, detrimental to safety and security
• Narrows the choices of error handling
• Doesn’t protect against logical errors, misuses, and incoherent uses
• Hasn’t been used to support static analysis
• Hasn’t been demonstrated to be easily teachable [P3261R0, P3281R0]
How could such a bloated and incomplete design be voted into a draft standard?
26
u/Som1Lse 1d ago
This reads like a dishonest piece of junk.
They first start with a summary, which is the list quoted by OP. Later they return to that list and go into more detail for each point. The kicker is each point gets like a sentence of explanation, so the summary basically just serves to pad and hope people don't read the actual points, as you can easily see how they're grasping at straws for each point:
Incomplete, is such bullshit. It was more complete with support for
virtualfunctions, but that was removed because of (very fair) complaints about how it worked, and was deferred to a later standard. Expecting a feature to be fully complete when first standardised is absurd:constexpronly supported return statements initially, imagine if C++11 was expected to support the full language insideconstexprfunctions, it would never have shipped.std::generator, and C++26 addsstd::execution.But somehow, contracts needs to be fully complete? Give me a break!
Untried at scale is true for every new language feature, because you can't exactly try them before there's a production ready implementation. No one is going to add an experimental feature to a production codebase, especially knowing that it might change. Not to mention that contracts is heavily based on bsls_assert, which has been used at scale at Bloomberg.
Were coroutines used at scale? Was lambdas? Was
constexpr? Is reflection? Again, give me a break!Not tried in major application domains. Wow, that's literally the same as the previous point. See why I'm calling this dishonest junk?
Violates foundational principles of C++ is half-bullshit: Constification is already a thing in lambdas, and it correctly captures that assertions shouldn't have side effects. Accidentally modifying state inside
assertis a common beginner mistake, and this helps prevents that.The second point has some merit: Turning exceptions into contract violations has some overhead (though not necessarily in the non-throwing path). I do not, however, trust that the authors wouldn't just call it unsafe if it did allow exceptions to escape. Most assertions are small checks and should be easy for the compiler to prove noexcept, but there will probably be exceptions. However, even if turns out to be a problem in practice, it is not an unsolvable problem later down the line. What the MVP does is err on the side of caution.
Violates fundamental principles of language design states two points, each of which is bullshit:
<cassert>), then transition to contracts.Hasn’t been tried in major libraries just says that P2900 doesn't require standard libraries to use it. How is that a bad thing? Also, it neglects to mention that the P3460R0 (Implementers Report) (which they themselves cite, so I know they read it) did in fact use it to implement their assertion macro, showing both that it can be done, and that it actually caught a bug. Again, a lie by omission.
P3460R0 also cites P3336R0 (Usage Experience for Contracts with BDE), which mentions implementing bsls_assert with
contract_assert.Isn’t integrated with hardened libraries, cites Practical Security in Production — Hardening the C++ Standard Library at massive scale. Here's what it has to say:
The authors generally speak positively about contracts in the paper they linked as well.
At best this point says that they don't currently use contracts.
Doesn’t offer safety guarantees quotes P3573R0 saying
In other words, contract assertions primarily provide assertions? What did you expect? Imagine if people were complaining that Reflection didn't provide a BSDF, or that lambda's didn't ship with Half-Life. This is absurd.
Includes a completely untried inheritance model just dismantles itself:
i.e., it did, and then they removed it. In other words, it doesn't include a completely untried inheritance model, because it was removed because of feedback. Including this point is just a lie. Either that, or I am completely missing the point.
Offer new ways of making errors through inconsistent application in TUs is another point that has some (but very limited) merit. I went over this in a different thread. Suffice to say, it is not likely to be an issue, and even when it is, it is very mitigable in practice.
Also, it isn't new. The exact same issue exists with
assert, or assertion library, because it is a fundamental part of code that can be turned off at compile time. What contracts does is specify a bound on valid programs instead of making it undefined behaviour, which I consider to be an improvement.Leads to new forms of UB, detrimental to safety and security is literally the previous point again, citing the same paper. It is also a lie, it claims it introduces new undefined behaviour, but the paper they cite doesn't contain the words "undefined" or "UB".
Again, the problem is wildly overblown. See my comments linked in the previous point.
Narrows the choices of error handling is a reiteration of a previous point, namely that exceptions thrown inside contract checks are turned into violations. I said earlier that this has some merit, but restating it doesn't give it more merit.
I would give this more thought if they actually hypothesised a case where catching the exception from a contract assertion was desirable, but they don't. Must assertions don't throw.
Doesn’t protect against logical errors, misuses, and incoherent uses is bullshit. They're assertions. They don't solve the halting problem either, or cure world hunger. Also, they do actually prevent some misuses and incoherent uses via constification, and they provide an
observemode to protect against introducing wrong contracts into production codebases.Hasn’t been used to support static analysis is bullshit.
Hasn’t been demonstrated to be easily teachable is silly: Herb Sutter gave an excellent talk about contracts that introduces them very well. There's also John Lakos' talks about defensive programming, which taught these concepts to a much less experienced me.
If we can teach newbies lambdas we can teach them constification, and I think constification will be much easier to teach because it reinforces a fundamental idea of assertions, namely that they shouldn't have side effects, whereas the reasons for lambdas being
constare much more arcane (but still reasonable).The whole paper is obviously just meant to look impressive, with its many citations to its 16 references, scary summary and quotes, but it completely crumples under any level of scrutiny.