Hacker News
points by quotemstr 4 days ago | 0 comments
Huh? Concepts are types of types. Contracts are fancier, structured runtime assertions. What does one have to do with the other? They're nothing alike.
[–] taybin 4 days ago
They both start with the letter C, have two syllables, and have/had a hard time getting into the standard. If you’re not paying close attention, it’s easy to get them confused.
[–] moomin 4 days ago
I’ll admit I only learned they were different today. I’d like to think that if I were a regular C++ user I’d be on top of this, though.
[–] jandrewrogers 4 days ago
That’s exactly my point.

Contracts notionally offer the ability to lift some runtime assertions to compile-time. That is how it was sold. Except they don’t in practice.

Meanwhile, concepts + constexpr if used artfully deliver that in practice, including for many cases that contracts were supposed to solve.

I push all verification to compile-time to the extent possible.

[–] quotemstr 4 days ago
I don't buy the idea that in "high-reliability C++" every condition worth checking can be checked statically, not unless you define "high-reliability" vacuously as that set of programs for which the claim is true. Real-world programs have legitimate reasons to verify invariants dynamically, and C++26 contracts provides an improved way to do so.

While the C++26 variant of contracts doesn't provide the benefits of its static-analysis-centric ancestor from 2014, and therefore isn't as consequential a feature, it still provides value to some and is absolutely not important enough to be worth killing a standard. Concepts do not provide this value.

In any case, it's simply false that C++26 contracts are unnecessary because we have concepts, yet this claim is the thrust of your initial comment.

[–] jandrewrogers 4 days ago
The issue is that contracts are less flexible than the existing capabilities in practice, it is limited syntactic sugar.

Contracts were sold with the idea of aiding compile-time verification, a noble purpose. The combination of concepts + constexpr allows you to do deeper compile-time verification today by other means than contracts can check. It isn’t obvious that this will ever not be the case. This means contracts is relegated to being another flavor of C asserts.

C++26 contracts are arguably unnecessary because we can achieve the same results other ways, sometimes with stronger properties. I’m a proponent of features that clean up the syntax but C++ contracts look like a nod to people that still use legacy C asserts. That’s fine but it also perpetuates an inadequate model of what assertions should be capable of expressing.

People figured out how to do with C++20 better than what contracts promised.

[–] quotemstr 4 days ago
There's nothing "legacy" about checking invariants at runtime, and you can't simultaneously dismiss the concerns of people doing so on the grounds that they're "still us[ing] legacy C asserts" when you deny them an alternative to "legacy C asserts". That's question-begging.

> People figured out how to do with C++20 better than what contracts promised.

What contracts used to promise is irrelevant. The contracts on the table modernized runtime assertions and are irrelevant to concepts, constexpr, and related facilities.

Is the contracts feature more useful than C's assert()?

If you want to argue that we're better off with the old macro, do so directly. Concepts, in this context, amount to irrelevant distraction.

[–] jandrewrogers 4 days ago
I have no issues with people check invariants at runtime. It is unavoidable. C++ contracts is a mediocre way of doing it. Many C++ code bases don’t use any macros at all for assertions and haven’t for a long time. Their models are much more nuanced than C++ contracts allows.

Why would anyone that already ditched C asserts use C++ contracts when it can’t express what the alternatives already can? This isn’t a new problem. People were creating more expressive assertion replacements than contracts offers a decade ago.

C++ contracts are nerfed. It is less expressive and capable than what anyone that cares about these things already uses. So who is expected to use it?

[–] rramadass 4 days ago
> Why would anyone that already ditched C asserts use C++ contracts when it can’t express what the alternatives already can?

You have not understood the C++26 contracts proposal.

It introduces three new syntax viz. "Pre" and "Post" in function signature declaration and a separate "contract_assert" which you can use anywhere in the code path.

It is the "Pre"/"Post" that is useful here. Since it is part of function signature declaration, a static analyzer can easily make sure that all function calls satisfy the contract else you get warning/error. The compiler on its part can inject appropriate code at the function boundary points to do runtime checking etc.

You cannot do this with assert macros. If you wanted something like this earlier, you would have had to change the compiler to emit modified function prologue/epilogue and build your own contract framework which few people had the capability to do.

You can now see the immediate benefits particularly for standard library (and other) code hardening needs. Many UB circumstances can be easily flagged at compile time without too much complexity.

Finally, note that if you use compile-time switch "ignore" to turn-off everything, only the runtime checks are elided (so you do not lose any performance) but the static analyzer can still catch all possible inconsistencies at compile-time thus giving you the best of both worlds.

[–] William_BB 4 days ago
> a static analyzer can easily make sure that all function calls satisfy the contract

How realistic is the "all function calls" part? Maybe I just don't see the bigger picture, but I would expect most function calls arguments to only be known at runtime, which of course makes static analysis not possible?

[–] rramadass 4 days ago
> While the C++26 variant of contracts doesn't provide the benefits of its static-analysis-centric ancestor from 2014

Do you have any information as to why they shifted the focus from static analysis to runtime checks? I only remember that it was based on some Microsoft annotation language or something.

[–] bluGill 4 days ago
Static analysis is hard. C++ 26 contracts are supposed to be the minimum viable feature that can be expanded on in future revisions.

Already the compiler is allowed to refuse to compile any code if it would guaranteed fail the contract. The next step is to see how far we can go with that static analysis and what those static analysis tools need to be better. However, this requires people having contracts in fairly widespread use so they can start trying their new ideas to see what happens when they hit the real world.

[–] rramadass 4 days ago
The original idea for C++ contracts was to implement something like Microsoft SAL notation (sometime in 2014) to enable full static analysis and that is what i was hoping for.

See my comment here - https://news.ycombinator.com/item?id=50361418

However, i also understand the reasoning behind this C++26 contracts proposition - https://news.ycombinator.com/item?id=50364593

While i understand the rationale here, i can also see the problems it might lead to in the future. Correctness concerns should be an all-or-nothing proposition, you cannot do it piecemeal. Hence whether you want to call it "profiles" or not, i would like a Eiffel/Ada-SPARK like system which gives me complete static compile-time analysis and verification along with separate run-time guarantees.

The contracts committee should go back to the drawing board and come up with a more comprehensive solution.

This is a real chance to finally realize the "Safe C++" dream! Ada did it and so can C++.