Boost logo

Boost :

Subject: Re: [boost] [outcome] Exception safety guarantees
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2017-05-28 01:02:54


On Sat, May 27, 2017 at 4:09 PM, Andrzej Krzemienski via Boost <
boost_at_[hidden]> wrote:

> 2017-05-28 0:55 GMT+02:00 Emil Dotchevski via Boost <boost_at_[hidden]
> >:
>
> > On Sat, May 27, 2017 at 3:15 PM, Andrzej Krzemienski via Boost <> Note
> that there is no provision to report a
> > failure (to establish the invariants) except by throwing. This is not an
> > omission but a deliberate design choice.
> >
>
> Interesting. I do not know what you mean here. Maybe, "there is no other
> way to report such failure except to throw an exception"? If so, I agree,
> but how does this relate to the discussed topic?
>

What I am demonstrating is that the C++ semantics for initialization and
destruction of objects have a built-in assumption about what constitutes a
valid object. Can you define this as "the only safe thing to do with x is
call is_valid()" on it? Sure, but then you're operating as a C programmer.
Consider what a C programmer has to do:

struct foo { /*state*/ };

void init_foo( foo * x )
{
   /*initialization*/
  assert(is_valid(x));
}

void destroy_foo( foo * x )
{
  assert(is_valid(x));
  //destroy *x
}

void use_foo( foo * x )
{
  assert(is_valid(x));
  /*use foo*/
}

And now compare this to a C++ program:

struct foo
{
  /*state*/
  foo()
  {
    /*initialization*/
  }

  ~foo()
  {
    /*destruction*/
  }

  void use()
  {
    /*use foo*/
  }
};

Note that in well designed C++ programs not only the asserts are not
necessary, they're downright silly. Is the object valid? Duh, of course it
is, or else the constructor would not have returned. But if you introduce a
"not quite valid" state, not only you need the asserts, you're making it
much more difficult for the user to reason about the state of the objects
in his program, just like a C programmer must.

If the user is handed an object, is it safe to use it? He could assume that
it is, but your design choice has rendered that an unsafe assumption,
because you're effectively reserving the right for the object to be
unusable. Alternatively, he could assume that he can't use it unless he
checks first. But now he's forced to write if( obj.is_valid() ) obj.use()
rather than obj.use().

What he is supposed to do in theory is analyze the program carefully and
determine for sure if in this particular case the object can be unusable.
In practice, there are so many corner cases that it is easy to get this
wrong, if not when the code is initially written, then under maintenance.
Such bugs are very difficult to detect, and infinitely more difficult to
detect in error handling code (where this "not quite valid" state would
occur, per your design.)

Granted, we're discussing a library specifically designed to support
programming without exceptions, so we're already in C territory as far as
object state is concerned.

Emil


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