<story><title>Adding design-by-contract conditions to C++ via a GCC plugin</title><url>https://gavinray97.github.io/blog/adding-invariant-to-cpp-design-by-contract</url></story><parent_chain></parent_chain><comment><author>josephg</author><text>Using invariants like this is now my preferred programming style. Almost all of my complex container classes have a dbg_check() method which checks all the internal invariants hold, and panics if not. When testing and debugging, I’ll add calls to dbg_check() after each mutation of my data structure. And then I write a fuzzer which exercises my API in a loop. Each iteration, I check that my invariants still hold.&lt;p&gt;The nice thing about this sort of invariant checking is that it makes it very fast and easy to narrow in on bugs. The crash happens right after a change which made the data invalid, not later when the invalid data is accessed.&lt;p&gt;And a few dozen lines of fuzz testing can find an extraordinary quantity of subtle bugs. It’s remarkable. Devastating for the ego, but remarkable.&lt;p&gt;&lt;i&gt;Edit:&lt;/i&gt;&lt;p&gt;Simple dbg_check implementation example: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;josephg&amp;#x2F;diamond-types&amp;#x2F;blob&amp;#x2F;3eb48478fd879e9f2bb9bcc6062762fbf2f8db21&amp;#x2F;src&amp;#x2F;causalgraph&amp;#x2F;check.rs&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;josephg&amp;#x2F;diamond-types&amp;#x2F;blob&amp;#x2F;3eb48478fd879e...&lt;/a&gt;&lt;p&gt;And here&amp;#x27;s a simple fuzz tester: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;josephg&amp;#x2F;jumprope-rs&amp;#x2F;blob&amp;#x2F;318e87d3aae1b2a0333042c7e75d30179c162f21&amp;#x2F;tests&amp;#x2F;test.rs#L202-L261&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;josephg&amp;#x2F;jumprope-rs&amp;#x2F;blob&amp;#x2F;318e87d3aae1b2a0...&lt;/a&gt;</text></comment>
<story><title>Adding design-by-contract conditions to C++ via a GCC plugin</title><url>https://gavinray97.github.io/blog/adding-invariant-to-cpp-design-by-contract</url></story><parent_chain></parent_chain><comment><author>Animats</author><text>I thought &amp;quot;contracts&amp;quot; were dropped out of C++20.[1]&lt;p&gt;Entry and exit assertions, and invariants, are powerful, especially when coupled with a proof of correctness system. But they&amp;#x27;re a tough retrofit.&lt;p&gt;Invariants have some issues. The general idea is that the invariant has to be true when control is outside the object. This was once the core idea of the object concept, although it&amp;#x27;s been somewhat forgotten. A big issue is, when does control enter and exit the object? What if you call a public member function from inside the object? Did you re-enter? What if you call out of an object to something that calls back in? What about recursion? What if another thread enters? Objects need clarity on the inside&amp;#x2F;outside issue for invariants to work. This is quite possible but a tough retrofit.&lt;p&gt;Invariants need syntax for talking about arrays and parts therof. You need quantifiers, or something like them. Lambdas?&lt;p&gt;From back when I did this sort of thing, decades ago, a simple SAT solver can eliminate the need to check over 90% of assertions at run time. So you want something like that, rather than trying to check everything at run time. Otherwise, nobody will keep the checks turned on.&lt;p&gt;All this is quite do-able. Most attempts to do it have suffered from academic overreach - the technology is pushed by people in love with formal methods, and the result is too complicated for routine use.&lt;p&gt;[1] &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;www.reddit.com&amp;#x2F;r&amp;#x2F;cpp&amp;#x2F;comments&amp;#x2F;cmk7ek&amp;#x2F;what_happened_to_c20_contracts&amp;#x2F;&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;www.reddit.com&amp;#x2F;r&amp;#x2F;cpp&amp;#x2F;comments&amp;#x2F;cmk7ek&amp;#x2F;what_happened_t...&lt;/a&gt;</text></comment>