C++ Logo

sg15

Advanced search

Re: [isocpp-sg15] [isocpp-sg21] P3835 -- Different contract checking for different libraries

From: Harald Achitz <harald_at_[hidden]>
Date: Fri, 17 Oct 2025 16:36:40 +0200
There are places in code where observe should not be even theoretically
an option.
A failed assertion/contract/check/call_it_what_ever has to have
consequence. Always. Not just in debug builds.
Many places are simple, 0 or 1. I have seen more of those then where
observe is relevant, but other people in other project might have seen
different scenarios.

/Harald

On 2025-10-17 16:23, Herb Sutter wrote:
>
> > Today's
>
> > void fun(Foo* ptr) {
>
> > my_supper_assert_macro (ptr!=nullpter);
>
> > my_supper_assert_macro(ptr->hasData());
>
> > }
>
> > should not have any problems, ever
>
> No, that’s not my understanding: Any assertion facility that offers
> log-and-continue (or similar “observe”) semantics will have the same
> issue.
>
> Many assertion libraries do offer that, don’t they? I did a quick
> Google search (errors are mine):
>
> * It seems that BOOST_CHECK and BOOST_TEST both continue, and so
> would have the same issue with this example.
> * Various assertion frameworks support a custom violation handler
> that could return instead of terminate/abort. If they return and
> do not abort, those would have the same issue again.
>
> It’s true that C assert() specifically doesn’t have that problem, but
> that’s only because it’s not powerful enough – it only offers “ignore”
> and “quick_enforce.” We do need observe semantics (we’ve already added
> it in our assertion libraries when C assert wasn’t enough), and as far
> as I can see any assertion facility with that feature has to have this
> characteristic for this example. So it seems to me this is a feature,
> not a bug.
>
> *From:*Harald Achitz <harald_at_[hidden]>
> *Sent:* Friday, October 17, 2025 6:54 AM
> *To:* Herb Sutter <herb.sutter_at_[hidden]>; sg15_at_[hidden];
> 'Ville Voutilainen' <ville.voutilainen_at_[hidden]>; sg21_at_[hidden]
> *Cc:* 'Tom Honermann' <tom_at_[hidden]>
> *Subject:* Re: [isocpp-sg15] [isocpp-sg21] P3835 -- Different contract
> checking for different libraries
>
> On 2025-10-17 15:28, Herb Sutter wrote:
>
> Harald asked:
>
> > On the internet I saw someone saying
>
> >
>
> > void fun(Foo* ptr) pre (ptr!=nullpter), pre(ptr->hasData()) { ... }
>
> >
>
> > might be a problem (for the second pre) and should be written
> like this
>
> >
>
> > void fun(Foo* ptr) pre (ptr!=nullpter && ptr->hasData()){ ... }
>
> >
>
> > is that true?
>
> With ignore, enforce, or quick_enforce there’s no issue. The
> second check will not be evaluated, no UB.
>
> With observe semantics (only), if the pointer is null then:
>
> 1. the first check fails, and gives a contract violation so you
> know it was violated
> 2. the second check then gives UB (no time travel, does not
> affect the first check that already happened)
>
> IMO the issue isn’t about contracts, it’s about short-circuit
> evaluation. This kind of issue can come up generally in the
> language if you split the (p) and (p->foo()) conditions, so we
> already teach that to get short-circuit evaluation you need to
> write the && using (p && p->foo()).
>
> This also comes up (again, generally throughout the language) with
> other examples like
>
> (is_sorted(v) && binary_search(v, x))
>
> because implementations of binary_search might try to perform
> unsafe out-of-bounds access if the range is not already sorted.
>
> In case it's helpful, here's the current slide I teach about that
> example (updated and extended since CppCon):
>
> Herb
>
> Thank you.
>
> Today's
>
> void fun(Foo* ptr) {
> my_supper_assert_macro (ptr!=nullpter);
> my_supper_assert_macro(ptr->hasData());
> }
>
> should not have any problems, ever
>
> so replacing this blindly against
>
> void fun(Foo* ptr) {
> contract_assert (ptr!=nullpter);
> contract_assert(ptr->hasData());
> }
>
> does not work, as I understand, since observe could be a problem?
>
> (I know now that when using pre I have to re-write with &&)
>
> /Harald
>

Received on 2025-10-17 14:36:43