Topic: throw exp;" - Should terminate() be called if exp throws?


Author: bouncer@dev.null (Wil Evers)
Date: Wed, 29 Oct 2003 18:00:15 +0000 (UTC)
Raw View
In article <uvfr4n5qk.fsf@boost-consulting.com>, David Abrahams wrote:

> bouncer@dev.null (Wil Evers) writes:
>
>> When we
>> throw, the throw-expression results in a temporary.  The compiler may
>> then decide to copy-construct that temporary, the stack unwinding
>> machinery takes over, and some associated handler is invoked.
>>
>> The question is: is the exception considered "active" when the copy
>> constructor is called?  If the answer is "yes", then it makes sense to
>> call terminate().   But if we say that the exception only becomes
>> active after the copy-constructor has done its job, then we have just
>> eliminated one reason for calling terminate().
>
> The copy-ctor may be called an arbitrary number of times during
> unwinding.

Let's see if my understanding of what the standard says about this is
correct.  If it is, then the following program will either print a 0 or a
1, but never something > 1.

  #include <iostream>

  struct ex {
    static int n_copy_ctor_calls;
    ex() { }
    ex(const ex&) { n_copy_ctor_calls++; }
  };

  int ex::n_copy_ctor_calls = 0;

  int main()
  {
    try {
      throw ex();
    } catch (const ex&) {
    }
    std::cout << ex::n_copy_ctor_calls << std::endl;
    return 0;
  }

Is that correct?

- Wil

--
Wil Evers, DOOSYS R&D BV, Utrecht, Holland
[Wil underscore Evers at doosys dot com]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rmaddox@isicns.com (Randy Maddox)
Date: Thu, 2 Oct 2003 22:14:24 +0000 (UTC)
Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<usmmfzug6.fsf@boost-consulting.com>...
> usenet1.spamfree.fusion@neverbox.com (Kevin Goodsell) writes:
>
> > My questions for this group are: 1) What is the correct interpretation
> > of that passage with respect to the above program? (Should it call
> > terminate() or catch the int exception?)
>
> It should catch the int exception.
>
> > 2) Is this passage ambiguous?
>
> Not in the least, AFAICT.  I can't imagine why people are saying that
> it is.  An expression which constructs a temporary hasn't been
> completely evaluated until that temporary has been completely
> constructed.
>
> --
> Dave Abrahams
> Boost Consulting
> www.boost-consulting.com
>

Let me summarize just to make sure I understand what is going on.

1) The statement "throw Except()" does not complete because the ctor
for Except() exits by throwing an exception.  Thus there is no issue
with an exception being thown during unwinding because the "throw
Except()" statement never completes.

2) The ctor for Except throws an int exception, which should then be
caught by the corresponding catch() statement.

3) The difference between this case and the footnote about an
exception thrown by an exception object's copy ctor is that in the
latter case the initial throw statement has completed so that the copy
ctor exception does occur in the context of stack unwinding, or at
least in the context of an already active exception that has not yet
been handled.

Is that correct?

Thanks.

Randy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 2 Oct 2003 23:57:10 +0000 (UTC)
Raw View
rmaddox@isicns.com (Randy Maddox) writes:

> dave@boost-consulting.com (David Abrahams) wrote in message news:<usmmfzug6.fsf@boost-consulting.com>...
>> usenet1.spamfree.fusion@neverbox.com (Kevin Goodsell) writes:
>>
>> > My questions for this group are: 1) What is the correct interpretation
>> > of that passage with respect to the above program? (Should it call
>> > terminate() or catch the int exception?)
>>
>> It should catch the int exception.
>>
>> > 2) Is this passage ambiguous?
>>
>> Not in the least, AFAICT.  I can't imagine why people are saying that
>> it is.  An expression which constructs a temporary hasn't been
>> completely evaluated until that temporary has been completely
>> constructed.
>
> Let me summarize just to make sure I understand what is going on.
>
> 1) The statement "throw Except()" does not complete because the ctor
> for Except() exits by throwing an exception.  Thus there is no issue
> with an exception being thown during unwinding because the "throw
> Except()" statement never completes.
>
> 2) The ctor for Except throws an int exception, which should then be
> caught by the corresponding catch() statement.
>
> 3) The difference between this case and the footnote about an
> exception thrown by an exception object's copy ctor is that in the
> latter case the initial throw statement has completed so that the copy
> ctor exception does occur in the context of stack unwinding, or at
> least in the context of an already active exception that has not yet
> been handled.
>
> Is that correct?

Precisely.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rmaddox@isicns.com (Randy Maddox)
Date: Fri, 3 Oct 2003 16:01:48 +0000 (UTC)
Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<uad8jl0t1.fsf@boost-consulting.com>...
> rmaddox@isicns.com (Randy Maddox) writes:
>
> > dave@boost-consulting.com (David Abrahams) wrote in message news:<usmmfzug6.fsf@boost-consulting.com>...
> >> usenet1.spamfree.fusion@neverbox.com (Kevin Goodsell) writes:
> >>
> >> > My questions for this group are: 1) What is the correct interpretation
> >> > of that passage with respect to the above program? (Should it call
> >> > terminate() or catch the int exception?)
> >>
> >> It should catch the int exception.
> >>
> >> > 2) Is this passage ambiguous?
> >>
> >> Not in the least, AFAICT.  I can't imagine why people are saying that
> >> it is.  An expression which constructs a temporary hasn't been
> >> completely evaluated until that temporary has been completely
> >> constructed.
> >
> > Let me summarize just to make sure I understand what is going on.
> >
> > 1) The statement "throw Except()" does not complete because the ctor
> > for Except() exits by throwing an exception.  Thus there is no issue
> > with an exception being thown during unwinding because the "throw
> > Except()" statement never completes.
> >
> > 2) The ctor for Except throws an int exception, which should then be
> > caught by the corresponding catch() statement.
> >
> > 3) The difference between this case and the footnote about an
> > exception thrown by an exception object's copy ctor is that in the
> > latter case the initial throw statement has completed so that the copy
> > ctor exception does occur in the context of stack unwinding, or at
> > least in the context of an already active exception that has not yet
> > been handled.
> >
> > Is that correct?
>
> Precisely.
>
> --
> Dave Abrahams
> Boost Consulting
> www.boost-consulting.com
>

Thanks.  This even makes sense to me now since there is a clear
dividing line between constructing the object to be thrown, and the
copying of that object by the exception mechanism.

Randy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bouncer@dev.null (Wil Evers)
Date: Fri, 3 Oct 2003 16:02:09 +0000 (UTC)
Raw View
In article <u3cef4kke.fsf@boost-consulting.com>, David Abrahams wrote:

> rmaddox@isicns.com (Randy Maddox) writes:
>
>> There is also a footnote 134 referenced at the end of the line quoted
>> above.  That footnote provides an example of an object being thrown
>> that has a copy ctor and states that if that ctor exits by throwing an
>> exception then terminate() is called.  It seems to me that your
>> example is quite similar in that the ctor for the object being thrown
>> exits by throwing an exception.
>
> But it's dissimilar in that the object whose constructor throws has
> not been thrown yet.  That's the key point.

Right.  So what we have is this:

  struct ex1 {
    ex1() { throw 42; }
  };

  struct ex2 {
    ex2() { }
    ex2(const ex2&) { throw 4711; }
  };

  void case1()
  {
    throw ex1(); // throws an int
  }

  void case2()
  {
    throw ex2(); // might result in a call to terminate()
  }

This makes me wonder why case 2 isn't handled like case 1, which is to
forget about the original exception and only report the exception escaping
from the copy constructor.  Calls to terminate() should be avoided unless
there is no way out, and in this case, I think there is.

Comments?

- Wil

--
Wil Evers, DOOSYS R&D BV, Utrecht, Holland
[Wil underscore Evers at doosys dot com]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: usenet1.spamfree.fusion@neverbox.com (Kevin Goodsell)
Date: Sat, 4 Oct 2003 01:45:33 +0000 (UTC)
Raw View
Wil Evers wrote:

> Right.  So what we have is this:
>
>   struct ex1 {
>     ex1() { throw 42; }
>   };
>
>   struct ex2 {
>     ex2() { }
>     ex2(const ex2&) { throw 4711; }
>   };
>
>   void case1()
>   {
>     throw ex1(); // throws an int
>   }
>
>   void case2()
>   {
>     throw ex2(); // might result in a call to terminate()
>   }
>
> This makes me wonder why case 2 isn't handled like case 1, which is to
> forget about the original exception and only report the exception escaping
> from the copy constructor.  Calls to terminate() should be avoided unless
> there is no way out, and in this case, I think there is.
>
> Comments?

You seem to be suggesting that an exception which occurs while another
exception is already "active" should take precedence. Do you really feel
this is acceptable in general? My understanding is that the committee
felt that there was no good solution to this problem - there's no
general way to determine which (if either) exception is "more important"
and should continue. Either choice loses information.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bouncer@dev.null (Wil Evers)
Date: Sat, 4 Oct 2003 18:36:09 +0000 (UTC)
Raw View
In article <mXjfb.270$Qy2.49@newsread4.news.pas.earthlink.net>, Kevin
Goodsell wrote:

> Wil Evers wrote:
>
>> Right.  So what we have is this:
>>
>>   struct ex1 {
>>     ex1() { throw 42; }
>>   };
>>
>>   struct ex2 {
>>     ex2() { }
>>     ex2(const ex2&) { throw 4711; }
>>   };
>>
>>   void case1()
>>   {
>>     throw ex1(); // throws an int
>>   }
>>
>>   void case2()
>>   {
>>     throw ex2(); // might result in a call to terminate()
>>   }
>>
>> This makes me wonder why case 2 isn't handled like case 1, which is to
>> forget about the original exception and only report the exception
>> escaping from the copy constructor.  Calls to terminate() should be
>> avoided unless there is no way out, and in this case, I think there
>> is.
>>
>> Comments?
>
> You seem to be suggesting that an exception which occurs while another
> exception is already "active" should take precedence.

That depends on when we consider the exception to become "active".  When we
throw, the throw-expression results in a temporary.  The compiler may then
decide to copy-construct that temporary, the stack unwinding machinery
takes over, and some associated handler is invoked.

The question is: is the exception considered "active" when the copy
constructor is called?  If the answer is "yes", then it makes sense to call
terminate().   But if we say that the exception only becomes active after
the copy-constructor has done its job, then we have just eliminated one
reason for calling terminate().

> Do you really feel
> this is acceptable in general? My understanding is that the committee
> felt that there was no good solution to this problem - there's no
> general way to determine which (if either) exception is "more important"
> and should continue. Either choice loses information.

Sure, we lose information, but I don't understand why losing information
because of an exception escaping from from the creation of the temporary is
different from losing information because of an exception escaping from the
copy-constructor.

The way things are now, using a data member (like a std::string) that has a
potentially throwing copy constructor in an exception class means we risk
killing the program.

- Wil

--
Wil Evers, DOOSYS R&D BV, Utrecht, Holland
[Wil underscore Evers at doosys dot com]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 5 Oct 2003 06:10:16 +0000 (UTC)
Raw View
bouncer@dev.null (Wil Evers) writes:

>> You seem to be suggesting that an exception which occurs while another
>> exception is already "active" should take precedence.
>
> That depends on when we consider the exception to become "active".  When we
> throw, the throw-expression results in a temporary.  The compiler may then
> decide to copy-construct that temporary, the stack unwinding machinery
> takes over, and some associated handler is invoked.
>
> The question is: is the exception considered "active" when the copy
> constructor is called?  If the answer is "yes", then it makes sense to call
> terminate().   But if we say that the exception only becomes active after
> the copy-constructor has done its job, then we have just eliminated one
> reason for calling terminate().

The copy-ctor may be called an arbitrary number of times during
unwinding.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Sun, 5 Oct 2003 20:50:18 +0000 (UTC)
Raw View
On Sun, 5 Oct 2003 06:10:16 +0000 (UTC), dave@boost-consulting.com
(David Abrahams) wrote:

> bouncer@dev.null (Wil Evers) writes:

> > That depends on when we consider the exception to become "active".  When we
> > throw, the throw-expression results in a temporary.  The compiler may then
> > decide to copy-construct that temporary, the stack unwinding machinery
> > takes over, and some associated handler is invoked.

> The copy-ctor may be called an arbitrary number of times during
> unwinding.

My read of these two statements indicates a mismatch.  Wil is talking
about the one and only temporary object constructed from the throw
expression, not any other copies made in catches.  That one which gets
rethrown by throw;.

Consider:

   throw E("something");

15.1/3 states that the operand of throw is like a function call
argument or the operand of return.  Here we have construction of
a temporary object E which is then used to copy construct the
special temporary.  As always, two temporaries may be considered
to be the same and reduced to one.  If the construction of the
first temporary throws, terminate is not called.  If that
construction does not throw and the copy ctor throws, terminate
is called.  If the temporaries are reduced and the special
temporary is direct initialized the copy ctor does not have a
chance to throw and terminate is not called.  If the direct
initializer throws, is terminate called?  Consistent?

The implementations which I have checked always make a copy.  It
seems that the possibility of either ctor throwing requires that
the copy be made otherwise optimization could change the meaning
of the program.  Alternatively, terminate is never called during
construction of the special temporary.

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: usenet1.spamfree.fusion@neverbox.com (Kevin Goodsell)
Date: Mon, 29 Sep 2003 05:14:23 +0000 (UTC)
Raw View
[This is a repost with some editing of a message I previously sent to
gnu.g++.help. That message can be viewed here:
http://groups.google.com/groups?selm=6Zlcb.1927%24NX3.713%40newsread3.news.pas.earthlink.net]

In a recent thread in comp.lang.c++, we were discussing what should
happen in the following case:

#include <iostream>

class Except
{
public:
   Except() { throw 1; }
};

int main()
{
   try {
     throw Except();
   }
   catch (Except) {
     std::cout << "Caught Except" << std::endl;
   }
   catch (int) {
     std::cout << "Caught int" << std::endl;
   }

   return 0;
}

The thread can be viewed here:
http://groups.google.com/groups?threadm=KGMbb.3867%24vS.1897%40newsread3.news.pas.earthlink.net

Given this, at least one popular compiler generates code that calls
terminate(). Earlier versions of that compiler and at least a few other
popular compilers generate code that catches the int exception.

I think catching the int is the correct thing to do, based on this (from
a public draft):

   15.5.1  The terminate() function                    [except.terminate]

1 In  the  following situations exception handling must be abandoned for
   less subtle error handling techniques:

   --when the exception handling mechanism, after  completing  evaluation
     of  the  expression  to be thrown but before the exception is caught
     (_except.throw_), calls a user function that exits via  an  uncaught
     exception,

<other cases snipped>

2 In such cases,
   void terminate();
   is called (_lib.exception.terminate_).

<snip>

Gianni Mariani on comp.lang.c++ stated that he felt this was ambiguous,
and questioned what could constitute completion of the expression to be
thrown - in particular, could terminating evaluation the expression due
to an exception be considered completing the expression? Guy Harrison on
gnu.g++.help also suggested that the text was "vague".

My questions for this group are: 1) What is the correct interpretation
of that passage with respect to the above program? (Should it call
terminate() or catch the int exception?) 2) Is this passage ambiguous?
And if so, 3) should a defect report be filed?

Thanks.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 29 Sep 2003 15:40:44 +0000 (UTC)
Raw View
"Kevin Goodsell" <usenet1.spamfree.fusion@neverbox.com> wrote in message
news:Md9db.5991$NX3.177@newsread3.news.pas.earthlink.net...
> [...]
> I think catching the int is the correct thing to do, based on this (from
> a public draft):
>
>    15.5.1  The terminate() function                    [except.terminate]
>
> 1 In  the  following situations exception handling must be abandoned for
>    less subtle error handling techniques:
>
>    --when the exception handling mechanism, after  completing  evaluation
>      of  the  expression  to be thrown but before the exception is caught
>      (_except.throw_), calls a user function that exits via  an  uncaught
>      exception,
> [...]

It seems to me that the terminate() behaviour is correct.  I'm not sure
what "completing evaluation" means exactly, but certainly a "user function
that exits via an uncaught exception" is being called "before the exception
is caught."  So it would appear that the intent here is to disallow this
"throwing while throwing" behaviour, and call terminate().  I think the
passage is not as clear as it could be, and certainly a note would help
in interpretation, at the least.

Dave



---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.518 / Virus Database: 316 - Release Date: 9/11/2003


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rmaddox@isicns.com (Randy Maddox)
Date: Mon, 29 Sep 2003 15:43:03 +0000 (UTC)
Raw View
usenet1.spamfree.fusion@neverbox.com (Kevin Goodsell) wrote in message news:<Md9db.5991$NX3.177@newsread3.news.pas.earthlink.net>...
> [This is a repost with some editing of a message I previously sent to
> gnu.g++.help. That message can be viewed here:
> http://groups.google.com/groups?selm=6Zlcb.1927%24NX3.713%40newsread3.news.pas.earthlink.net]
>
> In a recent thread in comp.lang.c++, we were discussing what should
> happen in the following case:
>
> #include <iostream>
>
> class Except
> {
> public:
>    Except() { throw 1; }
> };
>
> int main()
> {
>    try {
>      throw Except();
>    }
>    catch (Except) {
>      std::cout << "Caught Except" << std::endl;
>    }
>    catch (int) {
>      std::cout << "Caught int" << std::endl;
>    }
>
>    return 0;
> }
>
> The thread can be viewed here:
> http://groups.google.com/groups?threadm=KGMbb.3867%24vS.1897%40newsread3.news.pas.earthlink.net
>
> Given this, at least one popular compiler generates code that calls
> terminate(). Earlier versions of that compiler and at least a few other
> popular compilers generate code that catches the int exception.
>
> I think catching the int is the correct thing to do, based on this (from
> a public draft):
>
>    15.5.1  The terminate() function                    [except.terminate]
>
> 1 In  the  following situations exception handling must be abandoned for
>    less subtle error handling techniques:
>
>    --when the exception handling mechanism, after  completing  evaluation
>      of  the  expression  to be thrown but before the exception is caught
>      (_except.throw_), calls a user function that exits via  an  uncaught
>      exception,

There is also a footnote 134 referenced at the end of the line quoted
above.  That footnote provides an example of an object being thrown
that has a copy ctor and states that if that ctor exits by throwing an
exception then terminate() is called.  It seems to me that your
example is quite similar in that the ctor for the object being thrown
exits by throwing an exception.  Thus the Except object is never
successfully constructed, the throw statement cannot be completed, and
terminate() should be called.

I do agree that the wording could be a bit clearer.

Randy.

>
> <other cases snipped>
>
> 2 In such cases,
>    void terminate();
>    is called (_lib.exception.terminate_).
>
> <snip>
>
> Gianni Mariani on comp.lang.c++ stated that he felt this was ambiguous,
> and questioned what could constitute completion of the expression to be
> thrown - in particular, could terminating evaluation the expression due
> to an exception be considered completing the expression? Guy Harrison on
> gnu.g++.help also suggested that the text was "vague".
>
> My questions for this group are: 1) What is the correct interpretation
> of that passage with respect to the above program? (Should it call
> terminate() or catch the int exception?) 2) Is this passage ambiguous?
> And if so, 3) should a defect report be filed?
>
> Thanks.
>
> -Kevin
> --
> My email address is valid, but changes periodically.
> To contact me please use the address from a recent posting.
>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ark@acm.org (Andrew Koenig)
Date: Tue, 30 Sep 2003 05:34:39 +0000 (UTC)
Raw View
David> "Kevin Goodsell" <usenet1.spamfree.fusion@neverbox.com> wrote in message
David> news:Md9db.5991$NX3.177@newsread3.news.pas.earthlink.net...

>> [...]
>> I think catching the int is the correct thing to do, based on this (from
>> a public draft):
>>
>> 15.5.1  The terminate() function                    [except.terminate]
>>
>> 1 In  the  following situations exception handling must be abandoned for
>> less subtle error handling techniques:
>>
>> --when the exception handling mechanism, after  completing  evaluation
>> of  the  expression  to be thrown but before the exception is caught
>> (_except.throw_), calls a user function that exits via  an  uncaught
>> exception,
>> [...]

David> It seems to me that the terminate() behaviour is correct.  I'm
David> not sure what "completing evaluation" means exactly, but
David> certainly a "user function that exits via an uncaught
David> exception" is being called "before the exception is caught."
David> So it would appear that the intent here is to disallow this
David> "throwing while throwing" behaviour, and call terminate().  I
David> think the passage is not as clear as it could be, and certainly
David> a note would help in interpretation, at the least.

"Completing evaluation" means that the implementation has done
everything it needs to do in order to determine the value of the
expression.  So, for example, if I execute

        throw foo();

and foo throws an exception, then that exception is thrown *before*
completing evaluation of the expression "foo()".

I don't see any reason why an exception that occurs while evaluting
foo() should cause any behavior other than throwing that exception.

--
Andrew Koenig, ark@acm.org

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 30 Sep 2003 05:34:54 +0000 (UTC)
Raw View
rmaddox@isicns.com (Randy Maddox) writes:

> usenet1.spamfree.fusion@neverbox.com (Kevin Goodsell) wrote in message news:<Md9db.5991$NX3.177@newsread3.news.pas.earthlink.net>...
>> [This is a repost with some editing of a message I previously sent to
>> gnu.g++.help. That message can be viewed here:

>> I think catching the int is the correct thing to do, based on this (from
>> a public draft):
>>
>>    15.5.1  The terminate() function                    [except.terminate]
>>
>> 1 In  the  following situations exception handling must be abandoned for
>>    less subtle error handling techniques:
>>
>>    --when the exception handling mechanism, after  completing  evaluation
>>      of  the  expression  to be thrown but before the exception is caught
>>      (_except.throw_), calls a user function that exits via  an  uncaught
>>      exception,
>
> There is also a footnote 134 referenced at the end of the line quoted
> above.  That footnote provides an example of an object being thrown
> that has a copy ctor and states that if that ctor exits by throwing an
> exception then terminate() is called.  It seems to me that your
> example is quite similar in that the ctor for the object being thrown
> exits by throwing an exception.

But it's dissimilar in that the object whose constructor throws has
not been thrown yet.  That's the key point.

> Thus the Except object is never successfully constructed, the throw
> statement cannot be completed and terminate() should be called.

Nor can the throw even be started, so the footnote is inapplicable.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 30 Sep 2003 17:45:14 +0000 (UTC)
Raw View
usenet1.spamfree.fusion@neverbox.com (Kevin Goodsell) writes:

> My questions for this group are: 1) What is the correct interpretation
> of that passage with respect to the above program? (Should it call
> terminate() or catch the int exception?)

It should catch the int exception.

> 2) Is this passage ambiguous?

Not in the least, AFAICT.  I can't imagine why people are saying that
it is.  An expression which constructs a temporary hasn't been
completely evaluated until that temporary has been completely
constructed.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 30 Sep 2003 17:45:24 +0000 (UTC)
Raw View
dheld@codelogicconsulting.com ("David B. Held") writes:

> "Kevin Goodsell" <usenet1.spamfree.fusion@neverbox.com> wrote in message
> news:Md9db.5991$NX3.177@newsread3.news.pas.earthlink.net...
>> [...]
>> I think catching the int is the correct thing to do, based on this (from
>> a public draft):
>>
>>    15.5.1  The terminate() function                    [except.terminate]
>>
>> 1 In  the  following situations exception handling must be abandoned for
>>    less subtle error handling techniques:
>>
>>    --when the exception handling mechanism, after  completing  evaluation
>>      of  the  expression  to be thrown but before the exception is caught
>>      (_except.throw_), calls a user function that exits via  an  uncaught
>>      exception,
>> [...]
>
> It seems to me that the terminate() behaviour is correct.  I'm not sure
> what "completing evaluation" means exactly

It has the usual meaning.

   Except()

is an expression constructing a temporary.  Completing evaluating that
expression means completing construction of the Except() object.
Since the constructor throws, the construction never completes.  In
most ways,

     throw Except();

is no different from

     { Except x;  throw x; }

> but certainly a "user function that exits via an uncaught exception"
> is being called "before the exception is caught."

Not at all.  That statement relies on circular reasoning.  The user
function (Except::Except()) does throw an exception, but the
exception is caught.  That exception is thrown "before the exception
is throw", also, so the whole phrase doesn't apply.

> So it would appear that the intent here is to disallow this
> "throwing while throwing" behaviour

The intent is to disallow throwing while unwinding.  But in any case,
the second "throwing" in "throwing while throwing" never happens,
because the constructor doesn't complete.

> and call terminate().  I think the passage is not as clear as it
> could be, and certainly a note would help in interpretation, at the
> least.

Maybe, but it seems to me all the information needed is in there, as
long as we don't invent new meanings for "completing evaluation".

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gi2nospam@mariani.ws (Gianni Mariani)
Date: Tue, 30 Sep 2003 17:45:45 +0000 (UTC)
Raw View
Andrew Koenig wrote:
> David> "Kevin Goodsell" <usenet1.spamfree.fusion@neverbox.com> wrote in message
> David> news:Md9db.5991$NX3.177@newsread3.news.pas.earthlink.net...
>
>
>>>[...]
>>>I think catching the int is the correct thing to do, based on this (from
>>>a public draft):
>>>
>>>15.5.1  The terminate() function                    [except.terminate]
>>>
>>>1 In  the  following situations exception handling must be abandoned for
>>>less subtle error handling techniques:
>>>
>>>--when the exception handling mechanism, after  completing  evaluation
>>>of  the  expression  to be thrown but before the exception is caught
>>>(_except.throw_), calls a user function that exits via  an  uncaught
>>>exception,
>>>[...]
>
>
> David> It seems to me that the terminate() behaviour is correct.  I'm
> David> not sure what "completing evaluation" means exactly, but
> David> certainly a "user function that exits via an uncaught
> David> exception" is being called "before the exception is caught."
> David> So it would appear that the intent here is to disallow this
> David> "throwing while throwing" behaviour, and call terminate().  I
> David> think the passage is not as clear as it could be, and certainly
> David> a note would help in interpretation, at the least.
>
> "Completing evaluation" means that the implementation has done
> everything it needs to do in order to determine the value of the
> expression.  So, for example, if I execute
>
>         throw foo();
>
> and foo throws an exception, then that exception is thrown *before*
> completing evaluation of the expression "foo()".
>
> I don't see any reason why an exception that occurs while evaluting
> foo() should cause any behavior other than throwing that exception.
>

The above is a very reasonable interpretation of "completing evaluation".

However, there may be another, albeit possibly less reasonable,
interpretation that the expression "completed" evaluation at the point
that the exception is thrown.

It would seem to me that if the writer intended to allow for the throw
expression for itself to attempt to throw a second or more exceptions,
that would have been explicitly spelled out.

IMHO, I think a small clarification defect should be considered.






---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gi2nospam@mariani.ws (Gianni Mariani)
Date: Tue, 30 Sep 2003 17:45:38 +0000 (UTC)
Raw View
David Abrahams wrote:
> rmaddox@isicns.com (Randy Maddox) writes:
>
..
> But it's dissimilar in that the object whose constructor throws has
> not been thrown yet.  That's the key point.
>

According to your statement above, the OP's code below should
specifically exit 0 after writing "Caught int" right ?


....

#include <iostream>

class Except
{
public:
   Except() { throw 1; }
};

int main()
{
   try {
     throw Except();
   }
   catch (Except) {
     std::cout << "Caught Except" << std::endl;
   }
   catch (int) {
     std::cout << "Caught int" << std::endl;
   }

   return 0;
}

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 2 Oct 2003 22:13:00 +0000 (UTC)
Raw View
gi2nospam@mariani.ws (Gianni Mariani) writes:

> David Abrahams wrote:
>> rmaddox@isicns.com (Randy Maddox) writes:
>>
> ..
>> But it's dissimilar in that the object whose constructor throws has
>> not been thrown yet.  That's the key point.
>>
>
> According to your statement above, the OP's code below should
> specifically exit 0 after writing "Caught int" right ?

Right.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]