f



std::terminate() and std::unexpected()

Another post that would be better placed at csc ...

I'm looking for clarification on an issue in the standard. In 18.7.2.4
(std::unexpected()) and 18.7.3.3 (std::terminate()), the standards
says:
"2 Effects: Calls the unexpected_handler/terminate_handler function in
effect immediately after evaluating the throw-expression, if called by
the implementation, or calls the current unexpected_handler/
terminate_handler, if called by the program."

Consider this snippet:

------------------------
void fn1() { std::cerr << "fn1\n"; std::terminate(); }
void fn2() { std::cerr << "fn2\n"; std::terminate(); }

void foo() throw ()
{
  try {
    std::set_unexpected(&fn1);
    throw 0;
  } catch(...) {
    std::set_unexpected(&fn2);
    throw;
  }
}
------------------------

Should this program print fn1 or fn2?
In other words, does "the throw-expression" in the standardese refer
to the throw expression that created the exception object, or does it
refer to the most recent throw expression as defined in the grammar
([15]/1)?

GCC currently does not reload the handlers on rethrow, i.e. the above
program prints fn1, but I think this is a bug.

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

0
wasti
5/22/2008 1:54:56 PM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

8 Replies
916 Views

Similar Articles

[PageSpeed] 2

wasti.r...@gmx.net wrote:
> Consider this snippet:
>
> ------------------------
> void fn1() { std::cerr << "fn1\n"; std::terminate(); }
> void fn2() { std::cerr << "fn2\n"; std::terminate(); }
>
> void foo() throw ()
> {
>   try {
>     std::set_unexpected(&fn1);
>     throw 0;
>   } catch(...) {
>     std::set_unexpected(&fn2);
>     throw;
>   }
> }
> ------------------------
>
> Should this program print fn1 or fn2?

fn1. It seems like an open-and-shut case to me, unless I missing
something. when flow of control reaches 'throw 0' it has to call the
fn1 unexpected handler because that is the handler set up via the
previous line. fn2 wont be setup until it enters the catch(...) and it
wont do that because it calls fn1 first.

> GCC currently does not reload the handlers on rethrow, i.e. the above
> program prints fn1, but I think this is a bug.

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

0
marlow
5/30/2008 8:57:47 AM
marlow.andrew@googlemail.com wrote:

> wasti.r...@gmx.net wrote:
>> Consider this snippet:
>>
>> ------------------------
>> void fn1() { std::cerr << "fn1\n"; std::terminate(); }
>> void fn2() { std::cerr << "fn2\n"; std::terminate(); }
>>
>> void foo() throw ()
>> {
>>   try {
>>     std::set_unexpected(&fn1);
>>     throw 0;
>>   } catch(...) {
>>     std::set_unexpected(&fn2);
>>     throw;
>>   }
>> }
>> ------------------------
>>
>> Should this program print fn1 or fn2?
> 
> fn1. It seems like an open-and-shut case to me, unless I missing
> something. when flow of control reaches 'throw 0' it has to call the
> fn1 unexpected handler because that is the handler set up via the
> previous line. fn2 wont be setup until it enters the catch(...) and it
> wont do that because it calls fn1 first.

To, the case is not so open-and-shut, because the initial exception is
being caught within the function (and then re-thrown).
If you think that does not matter, do you also think that
std::unexpected must be called for this function:

 void foo() throw ()
 {
   try {
     std::set_unexpected(&fn1);
     throw 0;
   } catch(...) {
     std::set_unexpected(&fn2);
     if (std::rand() == 1)
     {
       throw;
     }
   }
 }

> 
>> GCC currently does not reload the handlers on rethrow, i.e. the above
>> program prints fn1, but I think this is a bug.
> 

>From my reading of the standard, I can't find any conclusive evidence
that favours one option over the other. I regard the behaviour to be
unspecified.

Bart v Ingen Schenau
-- 
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/

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

0
Bart
6/1/2008 5:45:37 PM
On 2 Jun, 01:45, Bart van Ingen Schenau <b...@ingen.ddns.info> wrote:
> >> void fn1() { std::cerr << "fn1\n"; std::terminate(); }
> >> void fn2() { std::cerr << "fn2\n"; std::terminate(); }
>
> >> void foo() throw ()
> >> {
> >>   try {
> >>     std::set_unexpected(&fn1);
> >>     throw 0;
> >>   } catch(...) {
> >>     std::set_unexpected(&fn2);
> >>     throw;
> >>   }
> >> }
> >> ------------------------
>
> >> Should this program print fn1 or fn2?

> >> GCC currently does not reload the handlers on rethrow, i.e. the above
> >> program prints fn1, but I think this is a bug.

Now I have re-read it, I can see I was wrong. I now see what you mean.
When the throw occurs fn1 is in operation but the exception is not
(yet) regarded as unexpected, so it goes into the catch. This ought to
result in fn2 being established as the unexpected handler. Then when
an exception is thrown from within the catch(...) and would escape all
the way to the top it is then treated as unexpected (since there is an
empty throw specification on the function). This should cause it to
invoke fn2 which is now the handler for unexpected. But it doesn't (at
least not with gcc). Have you tried it with any other compilers?

-Andrew Marlow

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

0
marlow
6/6/2008 9:15:47 AM
On 6 Jun., 18:15, marlow.and...@googlemail.com wrote:
> But it doesn't (at
> least not with gcc). Have you tried it with any other compilers?

Well, VC++ doesn't support set_unexpected. It prints fn2 for a similar
example using set_terminate, but I haven't tested that one on GCC yet.

Sebastian

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

0
wasti
6/6/2008 3:09:13 PM
On 6 Jun, 23:09, wasti.r...@gmx.net wrote:
> On 6 Jun., 18:15, marlow.and...@googlemail.com wrote:
>
> > But it doesn't (at
> > least not with gcc). Have you tried it with any other compilers?
>
> Well, VC++ doesn't support set_unexpected. It prints fn2 for a similar
> example using set_terminate, but I haven't tested that one on GCC yet.

Hmmm. So whatever the std says or means, the fact is that
set_unexpected is non-portable anyway! (thanks, Microsoft).

-Andrew Marlow


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

0
marlow
6/11/2008 6:23:49 AM
On Jun 6, 11:09 pm, wasti.r...@gmx.net wrote:
> On 6 Jun., 18:15, marlow.and...@googlemail.com wrote:
>
> > But it doesn't (at
> > least not with gcc). Have you tried it with any other compilers?
>
> Well, VC++ doesn't support set_unexpected. It prints fn2 for a similar
> example using set_terminate, but I haven't tested that one on GCC yet.

Which version of VC++?  VC5 and VC2008 are somewhat differant in how
well they implement the standard.  (And yes, there are still people
compiling code with VC5).

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

0
Martin
6/11/2008 7:32:00 PM
On Jun 12, 4:32 am, Martin Bonner <martinfro...@yahoo.co.uk> wrote:
> On Jun 6, 11:09 pm, wasti.r...@gmx.net wrote:
>
> > Well, VC++ doesn't support set_unexpected. It prints fn2 for a similar
> > example using set_terminate, but I haven't tested that one on GCC yet.
>
> Which version of VC++?  VC5 and VC2008 are somewhat differant in how
> well they implement the standard.  (And yes, there are still people
> compiling code with VC5).

I use 2003. It ignores exception specifications completely, except for
nothrow specifications, which are used for optimization only. (They're
mapped onto __declspec(nothrow).)

Sebastian

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

0
wasti
6/17/2008 1:07:53 PM
On 2008-06-17 22:07, wasti.redl@gmx.net wrote:
> On Jun 12, 4:32 am, Martin Bonner <martinfro...@yahoo.co.uk> wrote:
>> On Jun 6, 11:09 pm, wasti.r...@gmx.net wrote:
>>
>> > Well, VC++ doesn't support set_unexpected. It prints fn2 for a similar
>> > example using set_terminate, but I haven't tested that one on GCC yet.
>>
>> Which version of VC++?  VC5 and VC2008 are somewhat differant in how
>> well they implement the standard.  (And yes, there are still people
>> compiling code with VC5).
> 
> I use 2003. It ignores exception specifications completely, except for
> nothrow specifications, which are used for optimization only. (They're
> mapped onto __declspec(nothrow).)

Exception specifications is not supported in VC++ (any release) and
probably never will, it is not a useful enough feature (i.e. if you
start to use a lot exception specifications (other than nothrow) it soon
becomes unmanageable).

-- 
Erik Wikstr´┐Żm


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

0
UTF
6/17/2008 7:33:51 PM
Reply: