[exceptions] no-throw guarantee for trivial functions?

Discussion in 'C++' started by Maik, Jan 14, 2009.

  1. Maik

    Maik Guest

    Hello,

    I try to make more use of exceptions. One question which came to my
    mind is when to use the no-throw guarantee or not. Consider this:

    void do_something_harmless() throw() // good practice?
    { ... }

    void do_something_harmful_but_will_handle_it() throw()
    { ... }

    My feeling is that only functions (and ctors/dtors) whom bodies
    contain the catch em all statement "catch(...)" i.e
    {
    try { /*danger!*/ }
    /*other catch statements*/
    catch(...) { }
    }
    should be decorated with throw().

    Am I right?

    Thanks,
    -- Maik
    Maik, Jan 14, 2009
    #1
    1. Advertising

  2. Re: no-throw guarantee for trivial functions?

    On Jan 14, 1:41 pm, Maik <> wrote:

    > I try to make more use of exceptions.  One question which came to my
    > mind is when to use the no-throw guarantee or not.


    This does not buy you much.

    > Consider this:
    >
    >   void do_something_harmless()  throw() // good practice?
    >   { ... }
    >
    >   void do_something_harmful_but_will_handle_it() throw()
    >   { ... }
    >
    > My feeling is that only functions (and ctors/dtors) whom bodies
    > contain the catch em all statement "catch(...)" i.e
    >   {
    >     try { /*danger!*/ }
    >     /*other catch statements*/
    >     catch(...) { }
    >   }
    > should be decorated with throw().
    >
    > Am I right?


    Read the full story: http://www.gotw.ca/publications/mill22.htm

    --
    Max
    Maxim Yegorushkin, Jan 14, 2009
    #2
    1. Advertising

  3. Maik

    James Kanze Guest

    Re: no-throw guarantee for trivial functions?

    On Jan 14, 2:41 pm, Maik <> wrote:

    > I try to make more use of exceptions. One question which came
    > to my mind is when to use the no-throw guarantee or not.
    > Consider this:


    > void do_something_harmless() throw() // good practice?
    > { ... }


    > void do_something_harmful_but_will_handle_it() throw()
    > { ... }


    > My feeling is that only functions (and ctors/dtors) whom
    > bodies contain the catch em all statement "catch(...)" i.e
    > {
    > try { /*danger!*/ }
    > /*other catch statements*/
    > catch(...) { }
    > }
    > should be decorated with throw().


    > Am I right?


    No. Most of the time, the functions for which a no-throw
    guarantee is appropriate are leaf functions, which only use
    basic operations which are garanteed not to throw (like
    assignment to a scalar type). No need for a try/catch block in
    those.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jan 14, 2009
    #3
  4. Maik

    Guest

    Re: no-throw guarantee for trivial functions?

    On 14 Jan., 15:29, Maxim Yegorushkin <>
    wrote:

    [snipped question about exception specifications]

    > On Jan 14, 1:41 pm, Maik <> wrote:
    > Read the full story:http://www.gotw.ca/publications/mill22.htm


    Whoa, that sounds devastating. I thought that the compiler would treat
    the exception specifications a bit different. I thought that if you
    specify that your function only throws a certain set of exceptions,
    then the compiler will not compile your function as long as your code
    is not guaranteed to throw only such exceptions:
    // foo will compile, since all statements inside it won't throw
    anything.
    int foo (int Param) throw (A)
    {
    return Param + 1;
    }

    // goo will compile, since all statement inside it will throw at most
    A.
    int goo (int Param) throw (A)
    {
    return foo (Param) + 1;
    }

    // joo won't compile: The used function hoo is not guaranteed to throw
    at most A.
    int hoo ();
    int joo () throw (A)
    {
    return hoo ();
    }

    // koo will compile: Though it uses a function that may throw
    anything, this call
    // is guarded by a try-catch-statement.
    int koo () throw (A)
    {
    try
    {
    return hoo ();
    }
    catch (...)
    {
    }
    return 0;
    }

    This way your compiler would help you to write code with exception
    specifications without any performance penalties, which are pretty
    useless anyway. Isn't that the way how Ada95 uses exception
    specifications?

    Regards,
    Stuart
    , Jan 15, 2009
    #4
  5. Maik

    James Kanze Guest

    Re: no-throw guarantee for trivial functions?

    On Jan 15, 4:28 pm, wrote:
    > On 14 Jan., 15:29, Maxim Yegorushkin <>
    > wrote:


    > [snipped question about exception specifications]


    > > On Jan 14, 1:41 pm, Maik <> wrote:
    > > Read the full story:http://www.gotw.ca/publications/mill22.htm


    > Whoa, that sounds devastating.


    Yes, but it's very dated, and doesn't correspond to the general
    consensus today.

    > I thought that the compiler would treat the exception
    > specifications a bit different. I thought that if you specify
    > that your function only throws a certain set of exceptions,
    > then the compiler will not compile your function as long as
    > your code is not guaranteed to throw only such exceptions:


    And how do you guarantee that?

    > This way your compiler would help you to write code with
    > exception specifications without any performance penalties,


    Exceptions specifications don't incure a performance penalty
    with a decent compiler, and can, in a few cases, even lead to
    improved optimization (probably only for empty ones, however).

    > which are pretty useless anyway. Isn't that the way how Ada95
    > uses exception specifications?


    Ada is a different language, with different constraints than
    C++.

    In practice, there are two useful "guarantees" with regards to
    exceptions:

    -- The function never throws anything. This guarantee is more
    or less necessary in a few critical places if you want to
    write exception safe code. In C++, it's expressed by using
    the "throw()" exception specifier.

    -- The function *will* throw a specific exception for a
    specific error condition. I've never seen any language
    support for this, in any language.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jan 15, 2009
    #5
  6. Maik

    Maik Guest

    Re: no-throw guarantee for trivial functions?

    On 14 Jan., 23:07, James Kanze <> wrote:

    > No.  Most of the time, the functions for which a no-throw
    > guarantee is appropriate are leaf functions, which only use
    > basic operations which are garanteed not to throw (like
    > assignment to a scalar type).  No need for a try/catch block in
    > those.
    >


    Thanks for your answer.

    So far I got the impression, that throw() makes most sense if the
    function does something harmfull, but ensure to handle everything.

    From what you wrote to dertop
    <quote>
    -- The function never throws anything. This guarantee is more
    or less necessary in a few critical places if you want to
    write exception safe code. In C++, it's expressed by using
    the "throw()" exception specifier
    </quote>
    I get you as follows: The decision when to decorate with throw()
    isn't dependent on whether the function body is covered by an catch
    (...) or is harmless by nature. It depends on whether I have to be
    exception safe or not.

    If this is true, I have to read more on this topic to be able do make
    this decision. Do you know some good readings on this?

    Thanks,
    -- Maik
    Maik, Jan 15, 2009
    #6
  7. Maik

    red floyd Guest

    Re: no-throw guarantee for trivial functions?

    On Jan 15, 11:21 am, Maik <> wrote:
    > On 14 Jan., 23:07, James Kanze <> wrote:
    >
    > > No.  Most of the time, the functions for which a no-throw
    > > guarantee is appropriate are leaf functions, which only use
    > > basic operations which are garanteed not to throw (like
    > > assignment to a scalar type).  No need for a try/catch block in
    > > those.

    >
    > Thanks for your answer.
    >
    > So far I got the impression, that throw() makes most sense if the
    > function does something harmfull, but ensure to handle everything.
    >
    > From what you wrote to dertop
    > <quote>
    >  -- The function never throws anything.  This guarantee is more
    >     or less necessary in a few critical places if you want to
    >     write exception safe code.  In C++, it's expressed by using
    >     the "throw()" exception specifier
    > </quote>
    > I get you as follows:  The decision when to decorate with throw()
    > isn't dependent on whether the function body is covered by an catch
    > (...) or is harmless by nature.  It depends on whether I have to be
    > exception safe or not.
    >
    > If this is true, I have to read more on this topic to be able do make
    > this decision.  Do you know some good readings on this?
    >


    Herb Sutter, "Exceptional C++"
    red floyd, Jan 15, 2009
    #7
  8. Maik

    James Kanze Guest

    Re: no-throw guarantee for trivial functions?

    On Jan 15, 8:21 pm, Maik <> wrote:
    > On 14 Jan., 23:07, James Kanze <> wrote:


    > > No. Most of the time, the functions for which a no-throw
    > > guarantee is appropriate are leaf functions, which only use
    > > basic operations which are garanteed not to throw (like
    > > assignment to a scalar type). No need for a try/catch block in
    > > those.


    > Thanks for your answer.


    > So far I got the impression, that throw() makes most sense if
    > the function does something harmfull, but ensure to handle
    > everything.


    Or doesn't do anything harmful, so there is nothing to handle.
    The classic use of throw() is on a member function swap, where
    the member function simply swaps pointers (which can't fail),
    rather than doing any sort of deep copy (which presumably could
    fail, with std::bad_alloc, if nothing else).

    Rether than worrying about such low-level details, you really
    want to start by studying the notions of exception safety, and
    the different possible guarantees you can offer. Only once
    you've understood what you're trying to acheve (and what you can
    acheve) will the rules become understandable. (Try googling for
    "exception safety guarantee", and look for anything written by
    David Abrahams. For starters:
    http://www.boost.org/community/exception_safety.html, although
    that may already assume a certain knowledge.)

    > From what you wrote to dertop
    > <quote>
    > -- The function never throws anything. This guarantee is more
    > or less necessary in a few critical places if you want to
    > write exception safe code. In C++, it's expressed by using
    > the "throw()" exception specifier
    > </quote>
    > I get you as follows: The decision when to decorate with throw()
    > isn't dependent on whether the function body is covered by an catch
    > (...) or is harmless by nature. It depends on whether I have to be
    > exception safe or not.


    It's a contractual guarantee. It depends on what you want to
    guarantee for the client code. Including in possible future
    versions. A throw() restricts the possible evolution of the
    function, but allows certain uses in client code that wouldn't
    be possible otherwise.

    Exception safety is a larger issue. *All* code must be
    exception safe, period. What it means to be exception safe,
    however, depends on the application, and at the class level,
    what guarantees you choose to offer (which is a design
    decision).

    > If this is true, I have to read more on this topic to be able
    > do make this decision. Do you know some good readings on
    > this?


    Most of what I know has come from discussions with David
    Abrahams, in news groups. Herb Sutter has also written on the
    subject at various times. Be aware that our understanding of
    the issues has evolved. Some earlier writings by Herb and by
    Tom Cargill paint a far more negative picture than what we now
    understand (although these writings played an important role in
    triggering our understanding).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jan 16, 2009
    #8
  9. Maik

    Guest

    Re: no-throw guarantee for trivial functions?

    > On Jan 15, 4:28 pm, wrote:
    > > I thought that the compiler would treat the exception
    > > specifications a bit different. I thought that if you specify
    > > that your function only throws a certain set of exceptions,
    > > then the compiler will not compile your function as long as
    > > your code is not guaranteed to throw only such exceptions:



    On 15 Jan., 16:41, James Kanze <> wrote:
    > And how do you guarantee that?


    I guessed my example with the functions foo, goo, hoo, joo, and koo
    pretty much demonstrated how such exception specifications could be
    treated by the compiler. All it had to do would be making compile-time
    checks that you fulfill your "throw"-promise.
    What do you think, would such a scheme make sense?

    > On Jan 15, 4:28 pm, wrote:
    > > which are pretty useless anyway. Isn't that the way how Ada95
    > > uses exception specifications?



    On 15 Jan., 16:41, James Kanze <> wrote:
    > Ada is a different language, with different constraints than
    > C++.


    Yes, sometimes one can envy the guys that can use such a good compiler
    (working in the industry, I'm pretty much bound to compilers that are
    understood by the majority of programmers).

    Thanks,
    Stuart
    , Jan 16, 2009
    #9
  10. Maik

    James Kanze Guest

    Re: no-throw guarantee for trivial functions?

    On Jan 16, 9:16 pm, wrote:
    > > On Jan 15, 4:28 pm, wrote:
    > > > I thought that the compiler would treat the exception
    > > > specifications a bit different. I thought that if you
    > > > specify that your function only throws a certain set of
    > > > exceptions, then the compiler will not compile your
    > > > function as long as your code is not guaranteed to throw
    > > > only such exceptions:


    > On 15 Jan., 16:41, James Kanze <> wrote:


    > > And how do you guarantee that?


    > I guessed my example with the functions foo, goo, hoo, joo,
    > and koo pretty much demonstrated how such exception
    > specifications could be treated by the compiler. All it had to
    > do would be making compile-time checks that you fulfill your
    > "throw"-promise. What do you think, would such a scheme make
    > sense?


    It might have made sense had exception specifications been there
    from the beginning. Today, there are too many existing
    functions which in fact can't throw, but don't have empty
    exception specifications.

    There's also the problem that some functions can only throw if
    passed specific arguments; if you check for those arguments
    before hand, and don't pass them, the function can't throw.
    Personally, I'd have nothing against requiring them to be in a
    try block anyway (with an abort in the catch clause, since we
    know it can't happen), but I'm afraid I'm in a minority here.

    > > On Jan 15, 4:28 pm, wrote:
    > > > which are pretty useless anyway. Isn't that the way how Ada95
    > > > uses exception specifications?


    > On 15 Jan., 16:41, James Kanze <> wrote:


    > > Ada is a different language, with different constraints than
    > > C++.


    > Yes, sometimes one can envy the guys that can use such a good
    > compiler (working in the industry, I'm pretty much bound to
    > compilers that are understood by the majority of programmers).


    The quality of the compiler is often independent of the quality
    of the language. But in general, there seems to be a rule that
    a well designed language can't become wide spread. Much of
    C++'s popularity stems from the fact that it derives from C.
    Many of its problems, too.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jan 17, 2009
    #10
  11. Maik

    Rune Allnor Guest

    Re: no-throw guarantee for trivial functions?

    On 16 Jan, 09:45, James Kanze <> wrote:

    > Rether than worrying about such low-level details, you really
    > want to start by studying the notions of exception safety, and
    > the different possible guarantees you can offer.  Only once
    > you've understood what you're trying to acheve (and what you can
    > acheve) will the rules become understandable.  (Try googling for
    > "exception safety guarantee", and look for anything written by
    > David Abrahams.  For starters:http://www.boost.org/community/exception_safety.html, although
    > that may already assume a certain knowledge.)


    Any suggestions for more material on exception safety?

    Rune
    Rune Allnor, Jan 17, 2009
    #11
  12. Re: no-throw guarantee for trivial functions?

    On Jan 15, 3:41 pm, James Kanze <> wrote:
    > On Jan 15, 4:28 pm, wrote:
    >
    > > On 14 Jan., 15:29, Maxim Yegorushkin <>
    > > wrote:
    > > [snipped question about exception specifications]
    > > > On Jan 14, 1:41 pm, Maik <> wrote:
    > > > Read the full story:http://www.gotw.ca/publications/mill22.htm

    > > Whoa, that sounds devastating.

    >
    > Yes, but it's very dated, and doesn't correspond to the general
    > consensus today.


    It would be interesting to know what the general consensus today is.

    []

    > Exceptions specifications don't incure a performance penalty
    > with a decent compiler,


    Could you post compiler names please?

    > and can, in a few cases, even lead to
    > improved optimization (probably only for empty ones, however).


    Could you show those cases please?

    []

    > In practice, there are two useful "guarantees" with regards to
    > exceptions:
    >
    >  -- The function never throws anything.  This guarantee is more
    >     or less necessary in a few critical places if you want to
    >     write exception safe code.  In C++, it's expressed by using
    >     the "throw()" exception specifier.


    Are you talking about overriding std::exception::what() or something
    else?

    What are those few critical places?

    --
    Max
    Maxim Yegorushkin, Jan 17, 2009
    #12
  13. Maik

    James Kanze Guest

    Re: no-throw guarantee for trivial functions?

    On Jan 17, 3:11 pm, Maxim Yegorushkin
    <> wrote:
    > On Jan 15, 3:41 pm, James Kanze <> wrote:


    > > On Jan 15, 4:28 pm, wrote:


    > > > On 14 Jan., 15:29, Maxim Yegorushkin <>
    > > > wrote:
    > > > [snipped question about exception specifications]
    > > > > On Jan 14, 1:41 pm, Maik <>
    > > > > wrote: Read the full
    > > > > story:http://www.gotw.ca/publications/mill22.htm
    > > > Whoa, that sounds devastating.


    > > Yes, but it's very dated, and doesn't correspond to the
    > > general consensus today.


    > It would be interesting to know what the general consensus
    > today is.


    That no-throw exception specifications are generally advisable,
    when applicable.

    > []


    > > Exceptions specifications don't incure a performance penalty
    > > with a decent compiler,


    > Could you post compiler names please?


    Could you post one where it does have a performance penalty. I
    don't know of one. (It certainly has none with Sun CC, nor
    g++.)

    > > and can, in a few cases, even lead to improved optimization
    > > (probably only for empty ones, however).


    > Could you show those cases please?


    Not off hand, but as always, the more information a compiler
    has, the better it can optimize. Calling a function without a
    no throw exception specification introduces an additional flow
    path into the program.

    > []


    > > In practice, there are two useful "guarantees" with regards
    > > to exceptions:


    > > -- The function never throws anything. This guarantee is more
    > > or less necessary in a few critical places if you want to
    > > write exception safe code. In C++, it's expressed by using
    > > the "throw()" exception specifier.


    > Are you talking about overriding std::exception::what() or
    > something else?


    Of course not.

    > What are those few critical places?


    Just about all destructors, for starters. swap() member
    functions, if you're using the swap idiom for assignment. More
    generally, any time you have to temporarily invalidate the
    invariants.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jan 17, 2009
    #13
  14. Maik

    Kai-Uwe Bux Guest

    Re: no-throw guarantee for trivial functions?

    James Kanze wrote:

    [snip]
    >> > Exceptions specifications don't incure a performance penalty
    >> > with a decent compiler,

    >
    >> Could you post compiler names please?

    >
    > Could you post one where it does have a performance penalty. I
    > don't know of one. (It certainly has none with Sun CC, nor
    > g++.)
    >
    >> > and can, in a few cases, even lead to improved optimization
    >> > (probably only for empty ones, however).

    >
    >> Could you show those cases please?

    >
    > Not off hand, but as always, the more information a compiler
    > has, the better it can optimize. Calling a function without a
    > no throw exception specification introduces an additional flow
    > path into the program.

    [snip]

    And so does calling a function with a no throw exception specification
    because, if I recall correctly, the specification is not enforced at
    compile time but at runtime. Should an unlisted exception try to escape the
    function, unexpected() will be called. That means, the control flow
    machinery is still in place, just the target for the jump is different.

    On the same note: the compiler does not really have _more_ information. It
    still has no guarantee that no exceptions will be thrown. It just has to
    take different measures to deal with them.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jan 17, 2009
    #14
  15. Maik

    James Kanze Guest

    Re: no-throw guarantee for trivial functions?

    On 17 jan, 23:19, Kai-Uwe Bux <> wrote:
    > James Kanze wrote:


    > [snip]


    > >> > Exceptions specifications don't incure a performance
    > >> > penalty with a decent compiler,


    > >> Could you post compiler names please?


    > > Could you post one where it does have a performance penalty.
    > > I don't know of one. (It certainly has none with Sun CC,
    > > nor g++.)


    > >> > and can, in a few cases, even lead to improved
    > >> > optimization (probably only for empty ones, however).


    > >> Could you show those cases please?


    > > Not off hand, but as always, the more information a compiler
    > > has, the better it can optimize. Calling a function without
    > > a no throw exception specification introduces an additional
    > > flow path into the program.


    > [snip]


    > And so does calling a function with a no throw exception
    > specification because, if I recall correctly, the
    > specification is not enforced at compile time but at runtime.


    But it's enforced by the usual exception handling mechanisms, in
    the called function. When compiling the caller, the compiler
    doesn't have to consider the possibility that the function may
    return somewhere else (e.g. a catch clause, or whatever is used
    to call the destructors).

    And of course, the usual exception handling mechanism doesn't
    have any runtime cost unless an exception is actually thrown.

    > Should an unlisted exception try to escape the function,
    > unexpected() will be called. That means, the control flow
    > machinery is still in place, just the target for the jump is
    > different.


    You can look at it that way, but the effective result is the
    same as if the called function had called abort. Unlike the
    case when there's no exception specification, there are no
    additional paths that are relevant in the calling function.

    > On the same note: the compiler does not really have _more_
    > information. It still has no guarantee that no exceptions will
    > be thrown. It just has to take different measures to deal with
    > them.


    It knows that no exceptions will perculate out of the functions,
    and thus, that there cannot be a precipitous jump to the
    destructors of local variables when the function is called.

    As an example of how this could affect optimization, imagine a
    class with all of its functions inline. The compiler can keep
    parts of the class in registers in some parts of the client
    function, because it can see all use of them. If you call a
    function which might throw, however, it has to somehow ensure
    that the class data is where the destructor expects it, and not
    just where it should be at the point of return from the
    function.

    --
    James Kanze
    James Kanze, Jan 18, 2009
    #15
    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. Kerri
    Replies:
    2
    Views:
    12,993
    Kevin Spencer
    Oct 27, 2003
  2. Replies:
    15
    Views:
    7,485
    Roedy Green
    Sep 8, 2005
  3. baibaichen

    trivial or non-trivial object

    baibaichen, Jan 12, 2006, in forum: C++
    Replies:
    3
    Views:
    880
    osmium
    Jan 12, 2006
  4. Emanuele D'Arrigo

    To throw or to throw not?

    Emanuele D'Arrigo, Nov 14, 2008, in forum: Python
    Replies:
    6
    Views:
    310
    Emanuele D'Arrigo
    Nov 15, 2008
  5. Roberto Giaffy
    Replies:
    13
    Views:
    453
    Alf P. Steinbach
    Apr 9, 2010
Loading...

Share This Page