Boost logo

Boost :

From: Rob Stewart (stewart_at_[hidden])
Date: 2005-09-28 15:55:37


From: brangdon_at_[hidden] (Dave Harris)
> In-Reply-To: <200509261722.j8QHMRms015648_at_[hidden]>
> stewart_at_[hidden] (Rob Stewart) wrote (abridged):
> > > (e) is false, then the __assume tells us the sequence won't be
> > > executed at all, and both it and the BOOST_ASSERT can be optimised
> > > away. Whatever it
> >
> > If (e) is false, then BOOST_ASSERT takes some action, be it
> > invoking assert() or something else.
>
> Only if it's not optimised away.
>
> Here's my thinking. For clarity I'll write it like this, factoring out the
> common sub-expression:
>
> if (e) {
> BOOST_ASSERT( true );
> __assume( true );
> }
> else {
> BOOST_ASSERT( false );
> __assume( false );
> }
>
> The compiler knows that __assume(false) can never be reached so it can
> optimise away the whole "else" clause - provided it can prove that the
> BOOST_ASSERT always returns. In general it is dangerous to put other stuff
> in the same control block as __assume(false), because you don't know how
> clever the compiler will be about proving stuff like that.

The optimizer could eliminate BOOST_ASSERT(true) and, of course,
__assume(true). Thus, the entire true part of the if can be
elided. That leaves you with:

   if (!e)
   {
      BOOST_ASSERT(false);
      __assume(false);
   }

The optimizer can't elide the entire else clause because
BOOST_ASSERT(false) is in it. Thus, the assertion would fire.

In this example, we're also ignoring any code following the
invocation of the hypothetical BOOST_ASSERT:

   BOOST_ASSERT(e);
   // do work

That can be represented (unfaithfully) as:

   if (e)
   {
      BOOST_ASSERT(true);
      __assume(true);
      // do work
   }
   else
   {
      BOOST_ASSERT(false);
      __assume(false);
      // do work
   }

The optimizer can turn that into this:

   if (e)
   {
      // do work, optimized for e == true
   }
   else
   {
      BOOST_ASSERT(false);
      // do work, optimized for e == false
   }

> In this case you could argue that the compiler /cannot/ prove that
> BOOST_ASSERT will return; indeed in many cases it won't return. Even so I
> think it is a bit dangerous, but I suppose it doesn't really matter.

I don't think that matters here.

-- 
Rob Stewart                           stewart_at_[hidden]
Software Engineer                     http://www.sig.com
Susquehanna International Group, LLP  using std::disclaimer;

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk