The "smart guarantee"?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David B. Held

    The "smart guarantee"?

    I wanted to post this proposal on c.l.c++.m, but my news
    server apparently does not support that group any more.

    I propose a new class of exception safety known as the
    "smart guarantee". Essentially, the smart guarantee
    promises to clean up resources whose ownership is
    passed into the function, for whatever defintion of "clean
    up" is most appropriate for the resource passed.
    Note that this is different from both the basic and the
    strong guarantee.

    According to David Abrahams, (here:
    http://www.boost.org/more/generic_exception_safety.html)
    the common guarantees are as follows:

    The basic guarantee: that the invariants of the
    component are preserved, and no resources
    are leaked.
    The strong guarantee: that the operation has either
    completed successfully or thrown an exception,
    leaving the program state exactly as it was before
    the operation started.
    The no-throw guarantee: that the operation will not
    throw an exception.

    Now, one could be pedantic and say that the strong
    guarantee doesn't really promise that the program state
    will be "exactly" as it was before the operation started,
    since there is now an exception object present in the
    state which was not present before (if an exception is
    thrown, of course). However, let us not dwell on that
    pedantry, but a different one: what if the "operation" is
    a function which receives ownership of a resource,
    like so:

    void foo(obj* p);

    foo(new obj);

    Now, before the function is called, a new object is
    created on the heap. However, the only reference
    to that object is bound to a parameter of foo(). So
    technically, foo() is free to allow the last (and only)
    reference to obj go out of scope, and still provide
    the strong guarantee. If an exception is thrown, foo()
    exits, and the object is still on the heap; hence, the
    program state is preserved. Thus, foo() can be
    strongly exception safe and leak a resource.

    Clearly, most implementors of foo() will try to properly
    dispose of p in the event of an exception. But now
    foo() doesn't offer the strong guarantee, because if
    an exception is thrown, the exit state will be different
    from the entry state. However, such an implementation
    of foo() still offers some measure of safety in the face
    of exceptions, and foo() may provide the strong
    guarantee for all of the state not including the
    resources whose ownership was transferred into the
    function.

    I propose to call this level of safety the "smart
    guarantee". It may seem like an obscure corner
    case which does not deserve a name of its own,
    because functions which take sole ownership of a
    resource are not so common. I argue that if the
    language receives fundamental support for move
    semantics, then such functions may, in fact, become
    more common; and thus this level of exception
    safety may become more relevant.

    I chose the name "smart" because that seems to
    connote an awareness of resources or some type
    of automatic management. Note that the smart
    guarantee is somewhat orthogonal to the basic and
    strong guarantee. So a function could provide the
    basic guarantee for local state, and the smart
    guarantee for ownership-transfer arguments.
    Or, it could offer the strong guarantee for all
    ownership-stable state, and the smart guarantee
    for ownership-transfer state. It is perhaps useful to
    call these situations the "smart basic guarantee"
    and the "smart strong guarantee", respectively.
    I think of the "smart guarantee" as the "smart
    strong guarantee" by default.

    To explicitly state that an operation does not
    provide the smart guarantee, but does provide
    one of the other guarantees, I would say that it
    provides the "simple basic" or "simple strong"
    guarantee. By default, "basic guarantee" and
    "strong guarantee" should mean the simple
    versions.

    Comments are welcome.

    Dave



  • David B. Held

    #2
    Re: The "smart guarantee" ?

    After some consideration, I realized that perhaps I
    misunderstood the intended meaning of the basic
    guarantee, and that most of what I suggest for the
    smart guarantee is, in fact, covered by the basic
    guarantee. However, I still maintain that there is a
    middle ground between the basic and the strong
    guarantee which should still be called the "smart
    guarantee". But I no longer believe it is orthogonal
    to the other guarantees. Rather, I believe it
    occupies a point on the ladder of exception safety.

    Consider a member or friend function which takes
    ownership of an external resource:

    class foo
    {
    // ...
    public:
    foo(obj* p)
    {
    try
    {
    some_init(p); // might throw
    }
    catch (...)
    {
    delete p;
    }
    }
    void acquire(obj* p)
    {
    foo(p).swap(*th is);
    }
    void swap(foo& f); // nothrow
    };

    Now, acquire() provides the basic guarantee,
    because foo's invariants are preserved, and p
    is not leaked if foo(p) throws. However, acquire()
    provides *more* than the basic guarantee,
    because more than the invariants are preserved.
    In fact, the entire state of foo is preserved. And
    yet, acquire() provides *less* than the strong
    guarantee, because it does not preserve the entire
    program state (because it deletes p).

    I contend that this level of safety is useful to identify,
    because it is analogous to the strong guarantee
    while not being the strong guarantee. You know
    that foo's state is preserved, even if the external
    state is not, and that can be a useful piece of
    information in analyzing foo's behaviour in the
    presence of exceptions.

    Dave



    Comment

    • Rob Williscroft

      #3
      Re: The "smart guarantee" ?

      David B. Held wrote in news:bj9l21$28n $1@news.astound .net:
      [color=blue]
      >
      > I wanted to post this proposal on c.l.c++.m, but my news
      > server apparently does not support that group any more.
      >
      >[/color]

      X-Post added.



      Additionally here are a number of newsservers that will give you
      readonly access I found allnews.readfre enews.net here:
      Frequenly Asked Questions from Users of my Free UseNet News Server List with Integrated Search utilities allows you to find servers that carry that 'Special' group you are looking for

      some apparently allow posting but I didn't check if any carry
      c.l.c++.m.


      [color=blue]
      > After some consideration, I realized that perhaps I
      > misunderstood the intended meaning of the basic
      > guarantee, and that most of what I suggest for the
      > smart guarantee is, in fact, covered by the basic
      > guarantee. However, I still maintain that there is a
      > middle ground between the basic and the strong
      > guarantee which should still be called the "smart
      > guarantee". But I no longer believe it is orthogonal
      > to the other guarantees. Rather, I believe it
      > occupies a point on the ladder of exception safety.
      >
      > Consider a member or friend function which takes
      > ownership of an external resource:
      >
      > class foo
      > {
      > // ...
      > public:
      > foo(obj* p)
      > {
      > try
      > {
      > some_init(p); // might throw
      > }
      > catch (...)
      > {
      > delete p;
      > }
      > }
      > void acquire(obj* p)
      > {
      > foo(p).swap(*th is);
      > }
      > void swap(foo& f); // nothrow
      > };
      >
      > Now, acquire() provides the basic guarantee,
      > because foo's invariants are preserved, and p
      > is not leaked if foo(p) throws. However, acquire()
      > provides *more* than the basic guarantee,
      > because more than the invariants are preserved.
      > In fact, the entire state of foo is preserved.[/color]

      Couldn't this be expressed as the the basic gaurantee +
      entire state is invariant?
      [color=blue]
      > And
      > yet, acquire() provides *less* than the strong
      > guarantee, because it does not preserve the entire
      > program state (because it deletes p).
      >
      > I contend that this level of safety is useful to identify,
      > because it is analogous to the strong guarantee
      > while not being the strong guarantee. You know
      > that foo's state is preserved, even if the external
      > state is not, and that can be a useful piece of
      > information in analyzing foo's behaviour in the
      > presence of exceptions.
      >[/color]

      What you need here is an example of a client of this
      new guarantee, the problem I see is that the service is
      offering to preserve its own state but not the clients.
      As a client I don't think I'd have any use for that.

      Rob.
      --


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.m oderated. First time posters: Do this! ]

      Comment

      • David Abrahams

        #4
        Re: The "smart guarantee" ?

        "David B. Held" <dheld@codelogi cconsulting.com > writes:
        [color=blue]
        > Consider a member or friend function which takes
        > ownership of an external resource:
        >
        > class foo
        > {
        > // ...
        > public:
        > foo(obj* p)
        > {
        > try
        > {
        > some_init(p); // might throw
        > }
        > catch (...)
        > {
        > delete p;
        > }
        > }
        > void acquire(obj* p)
        > {
        > foo(p).swap(*th is);
        > }
        > void swap(foo& f); // nothrow
        > };
        >
        > Now, acquire() provides the basic guarantee,
        > because foo's invariants are preserved, and p
        > is not leaked if foo(p) throws. However, acquire()
        > provides *more* than the basic guarantee,
        > because more than the invariants are preserved.
        > In fact, the entire state of foo is preserved. And
        > yet, acquire() provides *less* than the strong
        > guarantee, because it does not preserve the entire
        > program state (because it deletes p).
        >
        > I contend that this level of safety is useful to identify,[/color]

        That is really the key question. There's not actually a "ladder" of
        exception safety distinctions: it's a lattice. For example, you could
        imagine a similar guarantee which says that *this might change if an
        exception is thrown, but none of the arguments will be modified (in
        addition to the basic guarantee of course). There are an infinite
        number of other such distinctions.

        But you've put your finger on it: is your guarantee really useful? I
        chose to name the particular distinctions I did because they *were*
        useful for reasoning about program correctness. How would you use
        your guarantee in program design?
        [color=blue]
        > because it is analogous to the strong guarantee
        > while not being the strong guarantee.[/color]

        That, in itself, does *not* make it useful. The guarantee I invented
        above can make the same claims about being similar to the strong
        guarantee yet I've never heard of anyone using or wanting it. I
        could come up with any number of others.

        In fact, why should *this be special? It's an argument like all the
        others, except that it's "hidden".
        [color=blue]
        > You know that foo's state is preserved, even if the external state
        > is not, and that can be a useful piece of information in analyzing
        > foo's behaviour in the presence of exceptions.[/color]

        Anything *could* be useful, but the proof is in the pudding.
        Distinctions are useful in proportion to their starkness. If we
        labelled every point in the spectrum we would have a wide array of
        terms, but I claim it would leave us less powerful to identify program
        behaviors, not more.

        --
        Dave Abrahams
        Boost Consulting

        Comment

        • David B. Held

          #5
          Re: The &quot;smart guarantee&quot; ?

          "David Abrahams" <dave@boost-consulting.com> wrote in message
          news:ullt2bwqt. fsf@boost-consulting.com. ..[color=blue]
          > "David B. Held" <dheld@codelogi cconsulting.com > writes:
          > [...]
          > That is really the key question. There's not actually a
          > "ladder" of exception safety distinctions: it's a lattice.[/color]

          The set of all possible exception safety rules is a lattice,
          but the "known" rules form a non-decreasing hierarchy
          of state integrity. The basic guarantee only promises that
          in the event of an exception, state will be valid. The smart
          guarantee says that state will be known, and most of it
          will be unchanged. The strong and nothrow guarantee
          say that all state will be unchanged.
          [color=blue]
          > For example, you could imagine a similar guarantee
          > which says that *this might change if an exception is
          > thrown, but none of the arguments will be modified
          > (in addition to the basic guarantee of course).[/color]

          Yes, but can you cite one non-contrived instance in which
          this guarantee offers something useful?
          [color=blue]
          > There are an infinite number of other such distinctions.[/color]

          And most of the others are not useful, as you say below.
          [color=blue]
          > But you've put your finger on it: is your guarantee really
          > useful? I chose to name the particular distinctions I did
          > because they *were* useful for reasoning about
          > program correctness. How would you use your
          > guarantee in program design?[/color]

          Let's use your example, but tweak it a bit. Instead of using
          std::set, let's say we have a set container that uses pointer semantics, and
          that it takes ownership of the objects put
          into it. Furthermore, ptr_set::insert () gives the smart
          guarantee:

          template <class T>
          class SearchableStack
          {
          public:
          void push(T* t); // O(log n)
          void pop(); // O(log n)
          bool contains(T* t) const; // O(log n)
          T* top() const; // O(1)
          private:
          ptr_set<T> set_impl;
          std::list<ptr_s etset<T>::itera tor> list_impl;
          };

          /* 01 */ template <class T>
          /* 02 */ void SearchableStack <T>::push(T* t)
          /* 03 */ {
          /* 04 */ ptr_set<T>::ite rator i = set_impl.insert (t);
          /* 05 */ try
          /* 06 */ {
          /* 07 */ list_impl.push_ back(i);
          /* 08 */ }
          /* 09 */ catch(...)
          /* 10 */ {
          /* 11 */ set_impl.erase( i);
          /* 12 */ throw;
          /* 13 */ }
          /* 14 */ }

          The analysis would be the same as with your example
          except for line 4. Not only do we want ptr_set::insert ()
          to not change the set if it fails, we also want it to clean
          up t as well, so we can write code like so:

          SearchableStack <obj> s;
          s.push(new obj);
          [color=blue][color=green]
          > > because it is analogous to the strong guarantee
          > > while not being the strong guarantee.[/color]
          >
          > That, in itself, does *not* make it useful. The guarantee
          > I invented above can make the same claims about
          > being similar to the strong guarantee yet I've never
          > heard of anyone using or wanting it. I could come up
          > with any number of others.[/color]

          Yes, but your example is not similar to the strong
          guarantee in a useful way. My point is that the smart
          guarantee is similar to the strong guarantee for all of
          the state that you *wish* to be preserved, and only
          violates transaction semantics to fulfill the constraint
          that no resources are leaked. Since one does not need
          to modify *this to prevent resource leakage, such a
          property would not seem desirable.
          [color=blue]
          > In fact, why should *this be special? It's an argument
          > like all the others, except that it's "hidden".[/color]

          I don't think *this is particularly special. What *is* special
          is resources being bound to a function parameter with
          no other references. That is the case that merits special
          attention, IMO.
          [color=blue]
          > [...]
          > Anything *could* be useful, but the proof is in the
          > pudding. Distinctions are useful in proportion to their
          > starkness. If we labelled every point in the spectrum
          > we would have a wide array of terms, but I claim it
          > would leave us less powerful to identify program
          > behaviors, not more.[/color]

          True enough. And like I said before, ownership transfer
          may be rare enough that this distinction is not that
          useful. I can't list a bunch of use cases where the
          smart guarantee is an important part of exception safety
          analysis. But I think it does address what seems to be
          a flaw, or at least, a peculiarity, of the strong guarantee,
          without inventing new exception guidelines arbitrarily.

          Dave



          Comment

          • Alexander Terekhov

            #6
            Re: The &quot;smart guarantee&quot; ?


            "David B. Held" wrote:
            [...][color=blue]
            > Now, one could be pedantic and say that the strong
            > guarantee doesn't really promise that the program state
            > will be "exactly" as it was before the operation started,
            > since there is now an exception object present in the
            > state which was not present before (if an exception is
            > thrown, of course). However, let us not dwell on that
            > pedantry, but a different one: what if the "operation" is
            > a function which receives ownership of a resource,
            > like so:
            >
            > void foo(obj* p);[/color]

            then the "smart way" to tell the world about such incredible
            peculiarity is nothing but just-do-it-like-so:

            void foo(std::auto_p tr<obj> p);

            Oder?

            regards,
            alexander.

            Comment

            • David B. Held

              #7
              Re: The &quot;smart guarantee&quot; ?

              "Rob Williscroft" <rtw@freenet.RE MOVE.co.uk> wrote in message
              news:Xns93ED93E C57CDCukcoREMOV Efreenetrtw@195 .129.110.131...[color=blue]
              > [...]
              > X-Post added.[/color]

              Thanks.
              [color=blue]
              > [...]
              > Couldn't this be expressed as the the basic gaurantee +
              > entire state is invariant?[/color]

              Yes, but I think that it occurs often enough that it deserves
              its own name.
              [color=blue]
              > [...]
              > What you need here is an example of a client of this
              > new guarantee, the problem I see is that the service is
              > offering to preserve its own state but not the clients.
              > As a client I don't think I'd have any use for that.[/color]

              Here is the motivating example:

              void bar()
              {
              some_smart_ptr p(new obj);
              // do stuff
              }

              Have you ever written code like this before? In this case,
              you almost certainly don't want some_smart_ptr to
              preserve your state, because you are giving away your
              only reference to obj. Here is a perfect example of the
              strong guarantee being "more safe" than you really
              want. It should be obvious that you really do want the
              function (in this case, and probably most, a c'tor) to
              modify your state (by deleting your object) in the case of
              an exception, but you also want it to provide the strong
              guarantee for the rest of the state. So the guarantee
              *does* preserve the client's state *whose ownership
              is not transferred into the function*. The only state that
              the guarantee says it will modify is exactly that state
              which you would want it to modify anyway, which is
              ownership-transferred resources. Otherwise, it is the
              same as the strong guarantee.

              For example, if you had this instead:

              void baz()
              {
              a_deleter d;
              some_smart_ptr p(new obj, d);
              // do other stuff
              }

              the smart guarantee would say that d is unchanged in
              the event of an exception, even if a non-const & to d is
              passed in (for whatever reason). That's because
              ownership of d is not being transferred into the function.

              Dave




              [ See http://www.gotw.ca/resources/clcm.htm for info about ]
              [ comp.lang.c++.m oderated. First time posters: Do this! ]

              Comment

              • David B. Held

                #8
                Re: The &quot;smart guarantee&quot; ?

                "Alexander Terekhov" <terekhov@web.d e> wrote in message
                news:3F5A397D.1 E768820@web.de. ..[color=blue]
                > [...]
                > then the "smart way" to tell the world about such
                > incredible peculiarity is nothing but just-do-it-like-so:
                >
                > void foo(std::auto_p tr<obj> p);[/color]

                Ah, but what if foo() is none other than
                auto_ptr::auto_ ptr(T* p), or some other resource wrapper
                c'tor? And if it's so peculiar, why do we have auto_ptr?

                Dave



                Comment

                • Alexander Terekhov

                  #9
                  Re: The &quot;smart guarantee&quot; ?


                  "David B. Held" wrote:[color=blue]
                  >
                  > "Alexander Terekhov" <terekhov@web.d e> wrote in message
                  > news:3F5A397D.1 E768820@web.de. ..[color=green]
                  > > [...]
                  > > then the "smart way" to tell the world about such
                  > > incredible peculiarity is nothing but just-do-it-like-so:
                  > >
                  > > void foo(std::auto_p tr<obj> p);[/color]
                  >
                  > Ah, but what if foo() is none other than
                  > auto_ptr::auto_ ptr(T* p),[/color]

                  That thing is throw()-nothing.
                  [color=blue]
                  > or some other resource wrapper c'tor?[/color]


                  [color=blue]
                  > And if it's so peculiar, why do we have auto_ptr?[/color]

                  Irony aside, teleportation, you know.



                  regards,
                  alexander.

                  Comment

                  • Rob Williscroft

                    #10
                    Re: The &quot;smart guarantee&quot; ?

                    David B. Held wrote in news:bjc3be$j7d $1@news.astound .net:
                    [color=blue]
                    > "Rob Williscroft" <rtw@freenet.RE MOVE.co.uk> wrote in message[/color]
                    [color=blue][color=green]
                    >> Couldn't this be expressed as the the basic gaurantee +
                    >> entire state is invariant?[/color]
                    >
                    > Yes, but I think that it occurs often enough that it deserves
                    > its own name.
                    >[/color]

                    I think it already has (kind of), see below.

                    [snip][color=blue]
                    >
                    > Here is the motivating example:
                    >
                    > void bar()
                    > {
                    > some_smart_ptr p(new obj);
                    > // do stuff
                    > }
                    >
                    > Have you ever written code like this before? In this case,
                    > you almost certainly don't want some_smart_ptr to
                    > preserve your state, because you are giving away your
                    > only reference to obj. Here is a perfect example of the
                    > strong guarantee being "more safe" than you really
                    > want. It should be obvious that you really do want the
                    > function (in this case, and probably most, a c'tor) to
                    > modify your state (by deleting your object) in the case of
                    > an exception, but you also want it to provide the strong
                    > guarantee for the rest of the state.[/color]

                    Its the bit were you say "(by deleting your object)", Where I just
                    don't see it that way, once the paramiter has been succesfully
                    passed it belong's to the state of the function or ctor.
                    [color=blue]
                    > So the guarantee
                    > *does* preserve the client's state *whose ownership
                    > is not transferred into the function*. The only state that
                    > the guarantee says it will modify is exactly that state
                    > which you would want it to modify anyway, which is
                    > ownership-transferred resources. Otherwise, it is the
                    > same as the strong guarantee.
                    >
                    > For example, if you had this instead:
                    >
                    > void baz()
                    > {
                    > a_deleter d;
                    > some_smart_ptr p(new obj, d);
                    > // do other stuff
                    > }
                    >
                    > the smart guarantee would say that d is unchanged in
                    > the event of an exception, even if a non-const & to d is
                    > passed in (for whatever reason). That's because
                    > ownership of d is not being transferred into the function.
                    >[/color]

                    This seems to be about RAII intialization and who takes
                    responsibility for the (or any) exception guarantees eg:

                    void client_responsi ble()
                    {
                    std::auto_ptr< obj > p( new obj );
                    server( p.get() );
                    p.release();
                    }

                    server_responsa ble would be your example and then there's:

                    void its_a_contract( )
                    {
                    std::auto_ptr< obj > temp( new obj )
                    server( temp );
                    }

                    Note that both client_reponsib le() and its_a_contract( ) can be
                    adapted to a server() taking multiple resources but:

                    void wont_work()
                    {
                    server( new obj, new obj );
                    }

                    can't. If either of the new obj expressions throw's the the other
                    leaks.

                    Which all means that whatever function or ctor we are talking about
                    that offers the Smart Guarantee is also a resource initializer,
                    wether we call it that or not.

                    From: http://www.boost.org/more/generic_exception_safety.html

                    <quote>
                    The basic guarantee: that the invariants of the component are
                    preserved, and no resources are leaked.
                    </quote>

                    I think that covers a RAII initializer. Though perhaps if it isn't
                    obvious (i.e. smart_ptr<> is obviously RAII) that RAII symantics
                    apply, we should document that the function/ctor is a RAII
                    initializer.

                    Rob.
                    --


                    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                    [ comp.lang.c++.m oderated. First time posters: Do this! ]

                    Comment

                    • David B. Held

                      #11
                      Re: The &quot;smart guarantee&quot; ?

                      "Rob Williscroft" <rtw@freenet.RE MOVE.co.uk> wrote in message
                      news:Xns93F1B55 FC1A06ukcoREMOV Efreenetrtw@195 .129.110.130...[color=blue]
                      > [...]
                      > Its the bit were you say "(by deleting your object)", Where
                      > I just don't see it that way, once the paramiter has been
                      > succesfully passed it belong's to the state of the function
                      > or ctor.[/color]

                      Well, David Abrahams doesn't see it that way, and he
                      wrote the exception safety definitions you quote below.
                      [color=blue]
                      > [...]
                      > Note that both client_reponsib le() and its_a_contract( )
                      > can be adapted to a server() taking multiple resources[/color]

                      Just like you can build your own strong guarantee, but
                      it's still nice when a component provides it for you. In
                      some extreme cases, you can't build your own strong
                      guarantee (such as for non-copyable objects), but it
                      seems unlikely that there are any cases where you
                      couldn't build your own "smart guarantee".
                      [color=blue]
                      > but:
                      >
                      > void wont_work()
                      > {
                      > server( new obj, new obj );
                      > }
                      >
                      > can't. If either of the new obj expressions throw's the the
                      > other leaks.[/color]

                      Which is why this is a bad thing to do in general, and I've
                      never encountered a situation where I even *wanted* to
                      do this.
                      [color=blue]
                      > Which all means that whatever function or ctor we are
                      > talking about that offers the Smart Guarantee is also a
                      > resource initializer, wether we call it that or not.[/color]

                      I'm not sure what you mean by "resource initializer", but
                      consider a function like some_smart_poin ter::reset(T* p).
                      Is that still "resource initialization" ?
                      [color=blue]
                      > From: http://www.boost.org/more/generic_exception_safety.html[/color]

                      If you notice, I quoted this in my original post. You could
                      have just quoted my quote. ;)
                      [color=blue]
                      > <quote>
                      > The basic guarantee: that the invariants of the component are
                      > preserved, and no resources are leaked.
                      > </quote>
                      >
                      > I think that covers a RAII initializer. Though perhaps if it
                      > isn't obvious (i.e. smart_ptr<> is obviously RAII) that RAII
                      > symantics apply, we should document that the function/ctor
                      > is a RAII initializer.[/color]

                      The basic guarantee is a necessary but not sufficient
                      condition of the smart guarantee. The point of the smart
                      guarantee is to go beyond preserving invariants, and say
                      that just about all of the state is actually preserved. After
                      all, preserving invariants isn't nearly as useful as
                      preserving state.

                      Dave




                      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                      [ comp.lang.c++.m oderated. First time posters: Do this! ]

                      Comment

                      • David Abrahams

                        #12
                        Re: The &quot;smart guarantee&quot; ?

                        "David B. Held" <dheld@codelogi cconsulting.com > wrote in message news:<bjdajo$nk d$1@news.astoun d.net>...[color=blue]
                        > "David Abrahams" <dave@boost-consulting.com> wrote in message
                        > news:ullt2bwqt. fsf@boost-consulting.com. ..[color=green]
                        > > "David B. Held" <dheld@codelogi cconsulting.com > writes:
                        > > [...]
                        > > That is really the key question. There's not actually a
                        > > "ladder" of exception safety distinctions: it's a lattice.[/color]
                        >
                        > The set of all possible exception safety rules is a lattice,
                        > but the "known" rules form a non-decreasing hierarchy
                        > of state integrity. The basic guarantee only promises that
                        > in the event of an exception, state will be valid. The smart
                        > guarantee says that state will be known, and most of it
                        > will be unchanged.[/color]

                        That isn't the way you characterized it before. Maybe you need to
                        nail down the definition.
                        [color=blue]
                        > The strong and nothrow guarantee say that all state will be unchanged.[/color]

                        Actually the nothrow guarantee says there will be no exception, so you
                        can draw any conclusion you like about what would happen if an
                        exception were to occur ;-)
                        [color=blue][color=green]
                        > > For example, you could imagine a similar guarantee
                        > > which says that *this might change if an exception is
                        > > thrown, but none of the arguments will be modified
                        > > (in addition to the basic guarantee of course).[/color]
                        >
                        > Yes, but can you cite one non-contrived instance in which
                        > this guarantee offers something useful?[/color]

                        Not offhand. I think that's my point; I'm offering you the same
                        challenge.
                        [color=blue][color=green]
                        > > But you've put your finger on it: is your guarantee really
                        > > useful? I chose to name the particular distinctions I did
                        > > because they *were* useful for reasoning about
                        > > program correctness. How would you use your
                        > > guarantee in program design?[/color]
                        >
                        > Let's use your example, but tweak it a bit. Instead of using
                        > std::set, let's say we have a set container that uses pointer semantics, and
                        > that it takes ownership of the objects put
                        > into it. Furthermore, ptr_set::insert () gives the smart
                        > guarantee:
                        >
                        > template <class T>
                        > class SearchableStack
                        > {
                        > public:
                        > void push(T* t); // O(log n)
                        > void pop(); // O(log n)
                        > bool contains(T* t) const; // O(log n)
                        > T* top() const; // O(1)
                        > private:
                        > ptr_set<T> set_impl;
                        > std::list<ptr_s etset<T>::itera tor> list_impl;
                        > };
                        >
                        > /* 01 */ template <class T>
                        > /* 02 */ void SearchableStack <T>::push(T* t)
                        > /* 03 */ {
                        > /* 04 */ ptr_set<T>::ite rator i = set_impl.insert (t);
                        > /* 05 */ try
                        > /* 06 */ {
                        > /* 07 */ list_impl.push_ back(i);
                        > /* 08 */ }
                        > /* 09 */ catch(...)
                        > /* 10 */ {
                        > /* 11 */ set_impl.erase( i);
                        > /* 12 */ throw;
                        > /* 13 */ }
                        > /* 14 */ }
                        >
                        > The analysis would be the same as with your example
                        > except for line 4. Not only do we want ptr_set::insert ()
                        > to not change the set if it fails, we also want it to clean
                        > up t as well, so we can write code like so:
                        >
                        > SearchableStack <obj> s;
                        > s.push(new obj);[/color]

                        Ah, OK. But then if you want this guarantee to be useful, *this can't
                        be special at all; there might be other persistent arguments which you
                        want to say haven't changed either. I think you just want to have a
                        way of labelling certain program state as changeable in case of an
                        exception. For this to be useful, you need to be explicit about which
                        state is changeable; it isn't enough to say "it offers the ``smart
                        guarantee''".

                        By the way, I think "smart guarantee" is a terrible name for this
                        idea. There's nothing dumb about it, but also nothing particularly
                        smart about it (as compared with the other guarantees).
                        [color=blue][color=green][color=darkred]
                        > > > because it is analogous to the strong guarantee
                        > > > while not being the strong guarantee.[/color]
                        > >
                        > > That, in itself, does *not* make it useful. The guarantee
                        > > I invented above can make the same claims about
                        > > being similar to the strong guarantee yet I've never
                        > > heard of anyone using or wanting it. I could come up
                        > > with any number of others.[/color]
                        >
                        > Yes, but your example is not similar to the strong
                        > guarantee in a useful way. My point is that the smart
                        > guarantee is similar to the strong guarantee for all of
                        > the state that you *wish* to be preserved, and only
                        > violates transaction semantics to fulfill the constraint
                        > that no resources are leaked. Since one does not need
                        > to modify *this to prevent resource leakage, such a
                        > property would not seem desirable.
                        >[color=green]
                        > > In fact, why should *this be special? It's an argument
                        > > like all the others, except that it's "hidden".[/color]
                        >
                        > I don't think *this is particularly special. What *is* special
                        > is resources being bound to a function parameter with
                        > no other references. That is the case that merits special
                        > attention, IMO.[/color]

                        But that's a feature of the caller, not of the callee!

                        SearchableStack s;
                        T* p = new T;
                        s.push(p);
                        p->whatever();

                        If you want to make it into a feature of the callee, pass a
                        std::auto_ptr by value. Then you know that nobody outside the caller
                        can legally use the pointer after the call, because the interface
                        enforces it. Since function arguments never survive a call and the
                        resource is wholly owned by the auto_ptr you can just say the function
                        gives the strong guarantee; end-of-story.
                        [color=blue][color=green]
                        > > [...]
                        > > Anything *could* be useful, but the proof is in the
                        > > pudding. Distinctions are useful in proportion to their
                        > > starkness. If we labelled every point in the spectrum
                        > > we would have a wide array of terms, but I claim it
                        > > would leave us less powerful to identify program
                        > > behaviors, not more.[/color]
                        >
                        > True enough. And like I said before, ownership transfer
                        > may be rare enough that this distinction is not that
                        > useful. I can't list a bunch of use cases where the
                        > smart guarantee is an important part of exception safety
                        > analysis.[/color]

                        That's my point.
                        [color=blue]
                        > But I think it does address what seems to be
                        > a flaw, or at least, a peculiarity, of the strong guarantee,
                        > without inventing new exception guidelines arbitrarily.[/color]

                        It's neither a flaw nor a peculiarity of the strong guarantee, IMO.
                        It covers the case perfectly when you use std::auto_ptr, and isn't
                        designed to cover the case otherwise. I don't believe the few authors
                        of smart pointers need a whole new distinction named for what they do
                        in their constructors in order to make the theory complete -- they can
                        just spell out the semantics directly. Furthermore, in an ideal world
                        (when we get template varargs or at least the forwarding problem
                        solved) nobody will write new-expressions directly anyway. Instead
                        we'll use factory functions like:

                        std::auto_ptr<T >::new_(arg1, arg2, arg3)

                        which are equivalent to:

                        std::auto_ptr<T >(new T(arg1,arg2,arg 3))

                        My 33 cents,
                        Dave

                        Comment

                        • David B. Held

                          #13
                          Re: The &quot;smart guarantee&quot; ?

                          "David Abrahams" <david.abrahams @rcn.com> wrote in message
                          news:ea97dfd9.0 309101627.7adc8 690@posting.goo gle.com...[color=blue]
                          > [...]
                          > That isn't the way you characterized it before.[/color]

                          I'm pretty sure it is, but I don't think it's worth the time to review.
                          [color=blue][color=green]
                          > > [Me]
                          > > Yes, but can you cite one non-contrived instance in which
                          > > this guarantee offers something useful?[/color]
                          >
                          > Not offhand. I think that's my point; I'm offering you the
                          > same challenge.[/color]

                          I offered some examples. I suppose you think containers
                          with pointer semantics are "contrived" , though, huh?
                          [color=blue]
                          > [...]
                          > Ah, OK. But then if you want this guarantee to be useful,
                          > *this can't be special at all;[/color]

                          I'm not sure where you got the idea that I said *this should
                          be handled specially.
                          [color=blue]
                          > there might be other persistent arguments which you
                          > want to say haven't changed either. I think you just want
                          > to have a way of labelling certain program state as
                          > changeable in case of an exception.[/color]

                          Yes.
                          [color=blue]
                          > For this to be useful, you need to be explicit about which
                          > state is changeable; it isn't enough to say "it offers the
                          > ``smart guarantee''".[/color]

                          Actually, I *was* explicit about which state is changeable.
                          The state that is changeable is dynamic resources whose
                          ownership is irreversibly transferred into the function. That
                          turns out to be the only state which you would *want* to
                          change in order to have a good safety guarantee.
                          [color=blue]
                          > By the way, I think "smart guarantee" is a terrible name
                          > for this idea. There's nothing dumb about it, but also
                          > nothing particularly smart about it (as compared with the
                          > other guarantees).[/color]

                          Actually, there is. It promises to give you the strong
                          guarantee except that it will do one smart thing and
                          automatically clean up resources. In the sense that "smart"
                          is used in other contexts to imply automatic management,
                          especially of resources, I think it is quite reasonable.
                          [color=blue]
                          > [...]
                          > SearchableStack s;
                          > T* p = new T;
                          > s.push(p);
                          > p->whatever();
                          >
                          > If you want to make it into a feature of the callee, pass a
                          > std::auto_ptr by value.[/color]

                          But if s were an auto_ptr<>, what would you do?

                          T* p = new T;
                          auto_ptr<T> s(p);

                          Why allow the inline new call in one context, but not another?
                          [color=blue]
                          > Then you know that nobody outside the caller can legally
                          > use the pointer after the call, because the interface
                          > enforces it. Since function arguments never survive a call
                          > and the resource is wholly owned by the auto_ptr you can
                          > just say the function gives the strong guarantee; end-of-
                          > story.[/color]

                          Yes. But this is a case of externally giving a stronger
                          guarantee, which is just like externally giving a function
                          the strong guarantee by copying the modifiable state first.
                          So then your argument is that no component should give
                          the strong guarantee because a client can always provide
                          it herself? If a function can provide the strong guarantee
                          efficiently, isn't it better if it does so?
                          [color=blue]
                          > [...][color=green]
                          > > But I think it does address what seems to be
                          > > a flaw, or at least, a peculiarity, of the strong
                          > > guarantee, without inventing new exception
                          > > guidelines arbitrarily.[/color]
                          >
                          > It's neither a flaw nor a peculiarity of the strong
                          > guarantee, IMO. It covers the case perfectly when you
                          > use std::auto_ptr, and isn't designed to cover the case
                          > otherwise.[/color]

                          But then, we don't need to have the strong guarantee,
                          since we can almost always provide it ourselves.
                          [color=blue]
                          > I don't believe the few authors of smart pointers need a
                          > whole new distinction named for what they do in their
                          > constructors[/color]

                          Don't forget reset(). ;>
                          [color=blue]
                          > in order to make the theory complete -- they can just
                          > spell out the semantics directly.[/color]

                          Ok, you caught me. ;) I was hoping that containers with
                          pointer semantics would provide another justification,
                          but they probably wouldn't add considerably to the
                          number of users who want the smart guarantee.
                          [color=blue]
                          > Furthermore, in an ideal world (when we get template
                          > varargs or at least the forwarding problem solved)
                          > nobody will write new-expressions directly anyway.
                          > Instead we'll use factory functions like:
                          >
                          > std::auto_ptr<T >::new_(arg1, arg2, arg3)
                          >
                          > which are equivalent to:
                          >
                          > std::auto_ptr<T >(new T(arg1,arg2,arg 3))[/color]

                          That would certainly be nice.

                          Dave



                          Comment

                          • David Abrahams

                            #14
                            Re: The &quot;smart guarantee&quot; ?


                            "David B. Held" <dheld@codelogi cconsulting.com > wrote in message
                            news:<bjdajo$nk d$1@news.astoun d.net>...
                            [color=blue]
                            > "David Abrahams" <dave@boost-consulting.com> wrote in message
                            > news:ullt2bwqt. fsf@boost-consulting.com. ..[color=green]
                            > > "David B. Held" <dheld@codelogi cconsulting.com > writes:
                            > > [...]
                            > > That is really the key question. There's not actually a
                            > > "ladder" of exception safety distinctions: it's a lattice.[/color]
                            >
                            > The set of all possible exception safety rules is a lattice,
                            > but the "known" rules form a non-decreasing hierarchy
                            > of state integrity. The basic guarantee only promises that
                            > in the event of an exception, state will be valid. The smart
                            > guarantee says that state will be known, and most of it
                            > will be unchanged.[/color]

                            That isn't the way you characterized it before. Maybe you need to
                            nail down the definition.
                            [color=blue]
                            > The strong and nothrow guarantee say that all state will be unchanged.[/color]

                            Actually the nothrow guarantee says there will be no exception, so you
                            can draw any conclusion you like about what would happen if an
                            exception were to occur ;-)
                            [color=blue][color=green]
                            > > For example, you could imagine a similar guarantee
                            > > which says that *this might change if an exception is
                            > > thrown, but none of the arguments will be modified
                            > > (in addition to the basic guarantee of course).[/color]
                            >
                            > Yes, but can you cite one non-contrived instance in which
                            > this guarantee offers something useful?[/color]

                            Not offhand. I think that's my point; I'm offering you the same
                            challenge.
                            [color=blue][color=green]
                            > > But you've put your finger on it: is your guarantee really
                            > > useful? I chose to name the particular distinctions I did
                            > > because they *were* useful for reasoning about
                            > > program correctness. How would you use your
                            > > guarantee in program design?[/color]
                            >
                            > Let's use your example, but tweak it a bit. Instead of using
                            > std::set, let's say we have a set container that uses pointer semantics, and
                            > that it takes ownership of the objects put
                            > into it. Furthermore, ptr_set::insert () gives the smart
                            > guarantee:
                            >
                            > template <class T>
                            > class SearchableStack
                            > {
                            > public:
                            > void push(T* t); // O(log n)
                            > void pop(); // O(log n)
                            > bool contains(T* t) const; // O(log n)
                            > T* top() const; // O(1)
                            > private:
                            > ptr_set<T> set_impl;
                            > std::list<ptr_s etset<T>::itera tor> list_impl;
                            > };
                            >
                            > /* 01 */ template <class T>
                            > /* 02 */ void SearchableStack <T>::push(T* t)
                            > /* 03 */ {
                            > /* 04 */ ptr_set<T>::ite rator i = set_impl.insert (t);
                            > /* 05 */ try
                            > /* 06 */ {
                            > /* 07 */ list_impl.push_ back(i);
                            > /* 08 */ }
                            > /* 09 */ catch(...)
                            > /* 10 */ {
                            > /* 11 */ set_impl.erase( i);
                            > /* 12 */ throw;
                            > /* 13 */ }
                            > /* 14 */ }
                            >
                            > The analysis would be the same as with your example
                            > except for line 4. Not only do we want ptr_set::insert ()
                            > to not change the set if it fails, we also want it to clean
                            > up t as well, so we can write code like so:
                            >
                            > SearchableStack <obj> s;
                            > s.push(new obj);[/color]

                            Ah, OK. But then if you want this guarantee to be useful, *this can't
                            be special at all; there might be other persistent arguments which you
                            want to say haven't changed either. I think you just want to have a
                            way of labelling certain program state as changeable in case of an
                            exception. For this to be useful, you need to be explicit about which
                            state is changeable; it isn't enough to say "it offers the ``smart
                            guarantee''".

                            By the way, I think "smart guarantee" is a terrible name for this
                            idea. There's nothing dumb about it, but also nothing particularly
                            smart about it (as compared with the other guarantees).
                            [color=blue][color=green][color=darkred]
                            > > > because it is analogous to the strong guarantee
                            > > > while not being the strong guarantee.[/color]
                            > >
                            > > That, in itself, does *not* make it useful. The guarantee
                            > > I invented above can make the same claims about
                            > > being similar to the strong guarantee yet I've never
                            > > heard of anyone using or wanting it. I could come up
                            > > with any number of others.[/color]
                            >
                            > Yes, but your example is not similar to the strong
                            > guarantee in a useful way. My point is that the smart
                            > guarantee is similar to the strong guarantee for all of
                            > the state that you *wish* to be preserved, and only
                            > violates transaction semantics to fulfill the constraint
                            > that no resources are leaked. Since one does not need
                            > to modify *this to prevent resource leakage, such a
                            > property would not seem desirable.
                            >[color=green]
                            > > In fact, why should *this be special? It's an argument
                            > > like all the others, except that it's "hidden".[/color]
                            >
                            > I don't think *this is particularly special. What *is* special
                            > is resources being bound to a function parameter with
                            > no other references. That is the case that merits special
                            > attention, IMO.[/color]

                            But that's a feature of the caller, not of the callee!

                            SearchableStack s;
                            T* p = new T;
                            s.push(p);
                            p->whatever();

                            If you want to make it into a feature of the callee, pass a
                            std::auto_ptr by value. Then you know that nobody outside the caller
                            can legally use the pointer after the call, because the interface
                            enforces it. Since function arguments never survive a call and the
                            resource is wholly owned by the auto_ptr you can just say the function
                            gives the strong guarantee; end-of-story.
                            [color=blue][color=green]
                            > > [...]
                            > > Anything *could* be useful, but the proof is in the
                            > > pudding. Distinctions are useful in proportion to their
                            > > starkness. If we labelled every point in the spectrum
                            > > we would have a wide array of terms, but I claim it
                            > > would leave us less powerful to identify program
                            > > behaviors, not more.[/color]
                            >
                            > True enough. And like I said before, ownership transfer
                            > may be rare enough that this distinction is not that
                            > useful. I can't list a bunch of use cases where the
                            > smart guarantee is an important part of exception safety
                            > analysis.[/color]

                            That's my point.
                            [color=blue]
                            > But I think it does address what seems to be
                            > a flaw, or at least, a peculiarity, of the strong guarantee,
                            > without inventing new exception guidelines arbitrarily.[/color]

                            It's neither a flaw nor a peculiarity of the strong guarantee, IMO.
                            It covers the case perfectly when you use std::auto_ptr, and isn't
                            designed to cover the case otherwise. I don't believe the few authors
                            of smart pointers need a whole new distinction named for what they do
                            in their constructors in order to make the theory complete -- they can
                            just spell out the semantics directly. Furthermore, in an ideal world
                            (when we get template varargs or at least the forwarding problem
                            solved) nobody will write new-expressions directly anyway. Instead
                            we'll use factory functions like:

                            std::auto_ptr<T >::new_(arg1, arg2, arg3)

                            which are equivalent to:

                            std::auto_ptr<T >(new T(arg1,arg2,arg 3))

                            My 33 cents,
                            Dave

                            --
                            Dave Abrahams
                            Boost Consulting


                            [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                            [ comp.lang.c++.m oderated. First time posters: Do this! ]

                            Comment

                            • David Abrahams

                              #15
                              Re: The &quot;smart guarantee&quot; ?

                              "David B. Held" <dheld@codelogi cconsulting.com > wrote in message news:<bjp5s0$b0 a$1@news.astoun d.net>...[color=blue]
                              > "David Abrahams" <david.abrahams @rcn.com> wrote in message
                              > news:ea97dfd9.0 309101627.7adc8 690@posting.goo gle.com...
                              >[color=green][color=darkred]
                              > > > Yes, but can you cite one non-contrived instance in which
                              > > > this guarantee offers something useful?[/color]
                              > >
                              > > Not offhand. I think that's my point; I'm offering you the
                              > > same challenge.[/color]
                              >
                              > I offered some examples. I suppose you think containers
                              > with pointer semantics are "contrived" , though, huh?[/color]

                              No. I do think that one shouldn't pass raw pointers to unmanaged
                              resources across their interface boundaries, though (or any interface
                              boundaries, for that matter). This is especially true because it
                              doesn't scale beyond one unmanaged resource parameter.
                              [color=blue][color=green]
                              > > [...]
                              > > Ah, OK. But then if you want this guarantee to be useful,
                              > > *this can't be special at all;[/color]
                              >
                              > I'm not sure where you got the idea that I said *this should
                              > be handled specially.[/color]

                              It was your use of the word "external" in:

                              I contend that this level of safety is useful to identify,
                              because it is analogous to the strong guarantee
                              while not being the strong guarantee. You know
                              that foo's state is preserved, even if the external
                              state is not, and that can be a useful piece of
                              information in analyzing foo's behaviour in the
                              presence of exceptions.
                              [color=blue][color=green]
                              > > there might be other persistent arguments which you
                              > > want to say haven't changed either. I think you just want
                              > > to have a way of labelling certain program state as
                              > > changeable in case of an exception.[/color]
                              >
                              > Yes.
                              >[color=green]
                              > > For this to be useful, you need to be explicit about which
                              > > state is changeable; it isn't enough to say "it offers the
                              > > ``smart guarantee''".[/color]
                              >
                              > Actually, I *was* explicit about which state is changeable.
                              > The state that is changeable is dynamic resources whose
                              > ownership is irreversibly transferred into the function.[/color]

                              Please, Dave: you didn't say that before. If you're saying that now,
                              fine. If you think I should've inferred it from what you said
                              earlier, please keep in mind that when you're talking about the EH
                              guarantees you're in the context of program specification and both
                              precision and explicitness count.

                              Try to think about how you'd write a precise description of your
                              guarantee, keeping in mind that transfer-of-ownership is a slippery
                              idea to nail down in specification. IMO the best way to deal with
                              situations like this one is to enforce the transfer-of-ownership in
                              the interface. Use auto_ptr if you can, or if you absolutely *must*
                              pass raw pointers, use a kind of smart pointer with implicit
                              conversion from T*. IMO the second-best way is to add to the
                              documentation "if an exception is thrown, p will be deleted". The
                              second-best way can be difficult when dealing with anything other than
                              constructors, though: _when_ will p be deleted? That's why it's only
                              second-best.
                              [color=blue]
                              > That turns out to be the only state which you would *want* to
                              > change in order to have a good safety guarantee.[/color]

                              Sure, for some broad definition of "resource" (another slippery
                              notion).
                              [color=blue][color=green]
                              > > By the way, I think "smart guarantee" is a terrible name
                              > > for this idea. There's nothing dumb about it, but also
                              > > nothing particularly smart about it (as compared with the
                              > > other guarantees).[/color]
                              >
                              > Actually, there is. It promises to give you the strong
                              > guarantee except that it will do one smart thing and
                              > automatically clean up resources. In the sense that "smart"
                              > is used in other contexts to imply automatic management,
                              > especially of resources, I think it is quite reasonable.[/color]

                              It's not a complete idea without the notion of which unmanaged
                              resources are being transferred.

                              <context you snipped>[color=blue][color=green][color=darkred]
                              > > > I don't think *this is particularly special. What *is* special
                              > > > is resources being bound to a function parameter with
                              > > > no other references. That is the case that merits special
                              > > > attention, IMO.[/color][/color][/color]
                              [color=blue][color=green]
                              > > But that's a feature of the caller, not of the callee![/color][/color]
                              </context you snipped>
                              [color=blue][color=green]
                              > > [...]
                              > > SearchableStack s;
                              > > T* p = new T;
                              > > s.push(p);
                              > > p->whatever();
                              > >
                              > > If you want to make it into a feature of the callee, pass a
                              > > std::auto_ptr by value.[/color]
                              >
                              > But if s were an auto_ptr<>, what would you do?
                              >
                              > T* p = new T;
                              > auto_ptr<T> s(p);
                              >
                              > Why allow the inline new call in one context, but not another?[/color]

                              To limit the scope of danger.
                              [color=blue][color=green]
                              > > Then you know that nobody outside the caller can legally
                              > > use the pointer after the call, because the interface
                              > > enforces it. Since function arguments never survive a call
                              > > and the resource is wholly owned by the auto_ptr you can
                              > > just say the function gives the strong guarantee; end-of-
                              > > story.[/color]
                              >
                              > Yes. But this is a case of externally giving a stronger
                              > guarantee, which is just like externally giving a function
                              > the strong guarantee by copying the modifiable state first.[/color]

                              No, it's the opposite. The guarantee is ensured *internally* to the
                              function, by its interface.
                              [color=blue]
                              > So then your argument is that no component should give
                              > the strong guarantee because a client can always provide
                              > it herself?[/color]

                              Huh?? How did you arrive at that conclusion?
                              [color=blue]
                              > If a function can provide the strong guarantee
                              > efficiently, isn't it better if it does so?[/color]

                              Generally, but I don't see how that relates to the issue at hand.
                              [color=blue][color=green]
                              > > [...][color=darkred]
                              > > > But I think it does address what seems to be
                              > > > a flaw, or at least, a peculiarity, of the strong
                              > > > guarantee, without inventing new exception
                              > > > guidelines arbitrarily.[/color]
                              > >
                              > > It's neither a flaw nor a peculiarity of the strong
                              > > guarantee, IMO. It covers the case perfectly when you
                              > > use std::auto_ptr, and isn't designed to cover the case
                              > > otherwise.[/color]
                              >
                              > But then, we don't need to have the strong guarantee,
                              > since we can almost always provide it ourselves.[/color]

                              Your line of argument, if you'll excuse me for saying so, is pure
                              nuttiness. If std::vector::pu sh_back didn't provide the strong
                              guarantee, how would you propose we can "provide it ourselves"?
                              [color=blue][color=green]
                              > > I don't believe the few authors of smart pointers need a
                              > > whole new distinction named for what they do in their
                              > > constructors[/color]
                              >
                              > Don't forget reset(). ;>[/color]

                              Personally I think having reset() at all is a design mistake. Show me
                              a reset() which can throw and I'll show you an even worse design
                              mistake.
                              [color=blue][color=green]
                              > > in order to make the theory complete -- they can just
                              > > spell out the semantics directly.[/color]
                              >
                              > Ok, you caught me. ;) I was hoping that containers with
                              > pointer semantics would provide another justification,
                              > but they probably wouldn't add considerably to the
                              > number of users who want the smart guarantee.[/color]

                              Especially not if properly designed. Consider how the range inserter
                              that takes three iterators should work on a deque with pointer
                              semantics. There's no way to track resource management if you pass a
                              range of raw pointers.

                              Comment

                              Working...