Remix.run Logo
▲ jandrewrogers 2 hours ago

As someone who writes high-reliability C++ but is completely outside the standards process, I see the issues with C++ Contracts. It isn’t clear that it solves a problem that anyone has in real codebases, especially after C++20 concepts.

If you were already writing high-reliability C++ then the benefits are difficult to quantify. If you weren’t writing high-reliability C++ then it saves you almost nothing over doing the standard idioms of high-reliability C++ that were already available to you at very marginally more cost. It does standardize expression of it in narrow cases but the payoff seems minimal.

Most of what C++ Contracts delivers is a mashup of what you can already do with constexpr and C++20 Concepts. I like reliability features but this feature, as delivered, looks fairly useless if you already use reliability features. A compelling standard would need to make much deeper guarantees out of the box. And the compiler can already see through most compositions of constexpr and C++20 concepts, which is already very expressive.

C++ Contracts looks a bit like a feature that was designed long before current standard features existed.

▲drivebyhooting 2 hours ago | parent | next [-]

Your comment just made me realize contracts is different from concepts (which are basically bounded genetics, right…?)

▲jandrewrogers 2 hours ago | parent | next [-]

C++ concepts evaluate the properties of types at compile-time. You can inject arbitrary constraints on type properties anywhere in the code including conditional codegen. It is a way of asking if a type “can express this complex set of abstract things or has this enumerated set of properties” with almost arbitrary detail. They are extremely powerful in terms of expressiveness and specialization of code. Insanely good for performance and reliability engineering.

One of the best features to be added to C++ in many years.

C++ contracts are an attempt to bring C asserts into the C++ age. The weakness of C++ contracts is that they are mostly syntactic sugar over C asserts. If you really care about this type of thing, you probably already have a custom C++ assertion framework that is at least as capable if not more.

The promise of C++ contracts is that they can aid formal verification, which would be great. As delivered, it can’t do much more than was already possible, which will inhibit adoption.

▲amluto an hour ago | parent | next [-]

I maintain a codebase that I’ve migrated from C++98 to C++11 and all the way to C++23 and even a bit of draft 26 (the latter for some minor library improvements). Few things made me quite as happy as moving from using SFINAE to using requires clauses and concepts.

(IMO the single best improvements over the years have been atomics and maybe variadic templates.)

▲jandrewrogers an hour ago | parent [-]

I think you are right to position atomics and variadic templates as among the most consequential features of C++ in the last couple decades. It made an enormous number of things possible.

One thing I give the C++ feature gods credit for is recognizing material deficiencies in systems languages and unapologetically trying to fill those gaps starting with C++11. The addition of atomics, strict variadics, constexpr, lambdas, concepts, lifetime annotations, etc has been transformative for C++.

▲AlotOfReading an hour ago | parent | prev [-]

    The weakness of C++ contracts is that they are mostly syntactic sugar over C asserts. 
The sugar is actually one of my issues with them. The evaluation semantics are much more complicated / potentially slower than C asserts because of the sugar, and why you would have to pay those costs isn't obvious at first glance. Lisa Lippincott's excellent talk on the design of contracts [0] is what switched me from a sort of neutral support to disliking it. I think it's a stupid place for the national bodies to draw the line though. std::regex is acceptable, but a nothingburger like contracts tanks the vote?

[0] https://www.youtube.com/watch?v=yhhSW-FSWkE

▲jandrewrogers an hour ago | parent [-]

To be clear, I have a lot of issues with the contracts proposal. I probably wouldn’t use despite living out on the standards frontier. I don’t even use C asserts already because they are not expressive enough in important ways. This proposal kind of reifies the inadequacies.

I think the risk is that C++ contracts become an evolutionary dead-end that hang around forever in code bases because they were standardized. It wouldn’t be the first time this has happened.

▲stingraycharles 2 hours ago | parent | prev | next [-]

Concepts are evaluated compile time and make a lot of TMP more elegant. Contracts are runtime check, akin to assertions.

Phrased differently, contracts are to concepts what assert is to static_assert.

▲YuechenLi an hour ago | parent | prev | next [-]

A concept is a compile time requirement that bounds templates which are the generics in C++, so you are close.

▲rramadass 2 hours ago | parent | prev [-]

Concepts are for Types at compile time while Contracts are for Values at runtime.

▲quotemstr 2 hours ago | parent | prev | next [-]

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 an hour ago | parent | next [-]

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.

▲jandrewrogers 2 hours ago | parent | prev | next [-]

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.

▲rramadass 2 hours ago | parent | prev [-]

Absolutely Right! - https://news.ycombinator.com/item?id=50361435

▲jibalt an hour ago | parent | prev [-]

[flagged]

▲locknitpicker 18 minutes ago | parent [-]

> The problem is that a bunch of people who didn't care for them did something very extreme by voting against approving C++26.

The only extreme and tone deaf thing I see in this story is how contracts proponents were faced with multiple papers demonstrating quite clearly and extensively how they were broken in specification and in form, but still tried to ignore all the criticism and force them through a consensus process in spite of being clearly opposed.

How does this make any sense? What was the plan here? To blackmail the C++ community to accept a broken feature under threat of the proposal not passing?

Make it make sense?

What I want to see is the people who tried to force contacts upon the process in spite of all opposition to come forth and explain their rationale. It was highly absurd and even unthinkable to force a broken feature down C++'s throats with bureaucratic chicanery, and then complain that the same bureaucracy has mechanisms to stop it's abuse. I for one would like to hear an explanation.