Exception safety in the STL

Discussion in 'C++' started by John Harrison, Jul 6, 2003.

  1. Where can I find information on exception safety in the STL? I.e. which
    methods on which types offer what level of exception safety.

    Josuttis has a useful list of classes and methods but he fails to mention
    common operations such as copy construction and assignment. I can't find any
    mention of this in my copy of the standard at all, although according to
    Josuttis exception safety guarantees are part of the standard.

    A specific question, I've looked at the gcc 3.2 and the VC++.NET
    implementation of list<T>::eek:perator= and neither appears to be exception
    safe. That is if an excpetion is thrown you could end up with a partially
    copied list. This surprises me, but is it OK according to the standard?

    john
    John Harrison, Jul 6, 2003
    #1
    1. Advertising

  2. In article <be8kmm$1vfjm$>, John Harrison
    <> wrote:

    | A specific question, I've looked at the gcc 3.2 and the VC++.NET
    | implementation of list<T>::eek:perator= and neither appears to be exception
    | safe. That is if an excpetion is thrown you could end up with a partially
    | copied list. This surprises me, but is it OK according to the standard?

    Yes, it is OK according to the standard. This is commonly called the
    basic guarantee. In such a situation you are guaranteed that if an
    exception is thrown, the list will remain in a self-consistent state.
    No list invariants will be violated. No memory will be leaked.

    In general, where the standard is silent, it is implying basic
    exception safety.

    It sounds like you are looking for strong exception safety: If an
    exception is thrown, the list will be left in the same state as it was
    before the operation began. This is also known as commit or rollback
    semantics.

    In general list::eek:perator= does not have the strong guarantee. But
    some implementations may offer exceptions to this standard defined
    behavior in certain circumstances. For example, the Metrowerks
    std::list<T>::eek:perator= offers the strong guarantee if T::eek:perator= is
    guaranteed not to throw. And this is accomplished with no additional
    expense of memory.

    If you have a std::container and you need to assign it with the strong
    guarantee, you can always do so at the expense of using more memory:

    template <class C>
    inline
    C&
    strong_assign(C& x, const C& y)
    {
    C(y).swap(x);
    return x;
    }

    Make a local copy of the source, and then swap that with the target.
    The copy may throw, since this is allocating memory, and calling
    C::value_type's copy constructor. If it does throw, the tempory
    container will clean up after itself. If it does not throw, then it
    is swapped into the target which is a no-throw operation.

    The strong assign is not "better" than the basic assign. It is simply
    different. Sometimes you need the basic, sometimes you need the
    strong. The basic assign will in general use less memory and thus be
    faster.

    --
    Howard Hinnant
    Metrowerks
    Howard Hinnant, Jul 6, 2003
    #2
    1. Advertising

  3. "Howard Hinnant" <> wrote in message
    news:060720030930125544%...
    > In article <be8kmm$1vfjm$>, John Harrison
    > <> wrote:
    >
    > | A specific question, I've looked at the gcc 3.2 and the VC++.NET
    > | implementation of list<T>::eek:perator= and neither appears to be exception
    > | safe. That is if an excpetion is thrown you could end up with a

    partially
    > | copied list. This surprises me, but is it OK according to the standard?
    >
    > Yes, it is OK according to the standard. This is commonly called the
    > basic guarantee. In such a situation you are guaranteed that if an
    > exception is thrown, the list will remain in a self-consistent state.
    > No list invariants will be violated. No memory will be leaked.
    >


    That surprises me because (according to Josuttis at least) list offers
    strong exception safety on most other operations (insert for instance). I
    guess this is so to avoid having to allocate extra memory.

    > In general, where the standard is silent, it is implying basic
    > exception safety.


    I still haven't been able to find the part of the standard that deals with
    this. Could you point out where it is?

    >
    > It sounds like you are looking for strong exception safety: If an
    > exception is thrown, the list will be left in the same state as it was
    > before the operation began. This is also known as commit or rollback
    > semantics.
    >
    > In general list::eek:perator= does not have the strong guarantee. But
    > some implementations may offer exceptions to this standard defined
    > behavior in certain circumstances. For example, the Metrowerks
    > std::list<T>::eek:perator= offers the strong guarantee if T::eek:perator= is
    > guaranteed not to throw. And this is accomplished with no additional
    > expense of memory.


    OK thanks, I'll take a look at the code.

    >
    > If you have a std::container and you need to assign it with the strong
    > guarantee, you can always do so at the expense of using more memory:
    >
    > template <class C>
    > inline
    > C&
    > strong_assign(C& x, const C& y)
    > {
    > C(y).swap(x);
    > return x;
    > }
    >
    > Make a local copy of the source, and then swap that with the target.
    > The copy may throw, since this is allocating memory, and calling
    > C::value_type's copy constructor. If it does throw, the tempory
    > container will clean up after itself. If it does not throw, then it
    > is swapped into the target which is a no-throw operation.
    >
    > The strong assign is not "better" than the basic assign. It is simply
    > different. Sometimes you need the basic, sometimes you need the
    > strong. The basic assign will in general use less memory and thus be
    > faster.
    >
    > --
    > Howard Hinnant
    > Metrowerks


    john
    John Harrison, Jul 6, 2003
    #3
  4. John Harrison

    Dhruv Guest

    On Sun, 06 Jul 2003 08:56:07 +0100, John Harrison wrote:

    Even I am having a lot of trouble with the STL exception safety. I'd like
    to know a thing. Suppose, I have a type whose destructor might throw. And
    I make a list of that type. So, that would mean that even the dtor of the
    list can throw. Am I correct?

    To John: You can find a good tabular form of what you are looking for in
    TC++PL, Special Edition, Pg 956. Basically, the Appendix E deals with
    exception safety.

    I kind of take it as a rule of thumb that dtors should not throw.
    Now, here, it is mentioned that clear() has a nothrow guarantee, but
    ~list() has no such guarantee? What to infer from this? Should I assume
    that since ~list() does verry little apart from calling clear(), it has
    the same exception specifications as clear().


    Regards,
    -Dhruv.
    Dhruv, Jul 7, 2003
    #4
  5. Alexander Terekhov, Jul 7, 2003
    #5
  6. "Alexander Terekhov" <> wrote in message
    news:...
    >
    > John Harrison wrote:
    > [...]
    > > > To John: You can find a good tabular form of what you are looking for

    in
    > > > TC++PL, Special Edition, Pg 956. Basically, the Appendix E deals with
    > > > exception safety.

    > >
    > > Thanks, I'll seek that out, I only have the regular edition.

    >
    > http://www.research.att.com/~bs/3rd_safe0.html
    >


    thanks, john
    John Harrison, Jul 8, 2003
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Philip V Pham

    STL (std) thread safety issues

    Philip V Pham, Jun 12, 2004, in forum: C++
    Replies:
    3
    Views:
    11,468
    Dietmar Kuehl
    Jun 14, 2004
  2. Luke Meyers

    STL exception safety, operator==

    Luke Meyers, Jan 5, 2006, in forum: C++
    Replies:
    0
    Views:
    355
    Luke Meyers
    Jan 5, 2006
  3. JDT

    STL safety issue

    JDT, Mar 14, 2007, in forum: C++
    Replies:
    3
    Views:
    305
    Thomas Tutone
    Mar 14, 2007
  4. grbgooglefan
    Replies:
    7
    Views:
    320
    James Kanze
    Dec 5, 2007
  5. Replies:
    6
    Views:
    1,027
    James Kanze
    Apr 5, 2008
Loading...

Share This Page