Remix.run Logo
▲ nananana9 6 hours 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.

▲bluGill 6 hours ago | parent | next [-]

I'm expecting to see talks (and buy books, read blogs...) in 3 years by someone who spent a lot of work adding contracts to a small but significant code base. This is the type of question they will answer.

I think the right answer is in the header, and in turn that means someone needs to answer your objection - how do you avoid long compiler times? I suspect modules is a large part of the answer, which means the guide/talk will also be how to make modules work in the real world. Remember though, that is all guesses I wouldn't be surprised if I'm wrong.

▲pjmlp 6 hours ago | parent [-]

C++ contracts design is based on an internal Bloomberg framework, see John Lakos recent talks on contracts.

▲bluGill 4 hours ago | parent [-]

Hmm, I thought I had watched all his talks on contracts by now, but I must have missed a few (which isn't a surprise - there are a lot of conferences out there that I can't watch them all and get anything done. I end up ignoring a lot of them)

▲pjmlp 3 hours ago | parent [-]

This was the latest where I saw him mentioning it.

"Our Journey Toward a Fully Backward-Compatible, UB-Safe, ISO C++"

https://youtu.be/whFzmXXhG5g?is=jSOnYkqr5nNULGkY

▲OneDeuxTriSeiGo 6 hours ago | parent | prev | next [-]

Strictly speaking you put them in the header.

The first declaration of a function must include the contract pre/post conditions and follow-up re-declarations of the function must either not include any contract conditions or the same conditions as the initial declaration.

And you can avoid re-including the world because pre/post conditions should be externally visible behavior or call out to functions for pre/post checks on internal behavior.

Essentially you either define them using what you have in scope during the initial declaration or you call out to a function located elsewhere that can have access to more/internal scope and do more complicated checks.

▲pjmlp 6 hours ago | parent | prev [-]

Since this is for C++26, you use modules.