logoalt Hacker News

nananana9 • today at 2:19 PM • 3 replies • view on HN

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.


Replies

bluGill • today at 2:43 PM

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.

➕ show 1 reply
OneDeuxTriSeiGo • today at 2:57 PM

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 • today at 2:53 PM

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