[Cfp-interest] more on try/catch
Rajan Bhakta
rbhakta at us.ibm.com
Fri May 30 07:01:44 PDT 2014
Just to make sure what we are doing is intended, I recall from the last
meeting we decided not to go with the try/catch style due to the opinion
it would be a hard sell to the C committee (and likely C compiler vendors
as well).
Have we decided to change that approach or are we still just making
proposals in case the #pragma or macro magic does not work?
Regards,
Rajan Bhakta
z/OS XL C/C++ Compiler Technical Architect
ISO C Standards Representative for Canada
C Compiler Development
Contact: rbhakta at us.ibm.com, Rajan Bhakta/Houston/IBM
From: Ian McIntosh <ianm at ca.ibm.com>
To: cfp-interest at ucbtest.org,
Date: 05/29/2014 10:16 PM
Subject: Re: [Cfp-interest] more on try/catch
Sent by: cfp-interest-bounces at oakapple.net
I thought I'd try approaching this from the opposite direction: How would
you change C++ to handle floating-point exceptions? Then could / how
could that be handled in C, and would that also work in C++?
So far C++ exceptions only come from throw statements, never from
floating-point exceptions (also never from traps, other hardware detected
events, or operating system detected events). Let's assume that is
changed so they can come from floating-point exceptions.
In C++, a catch clause catches an exception object according to its type,
not its value, then is optionally told the value.
- One way to use that is to define a "floating point exception" struct
type that contains something identifying which exception(s) happened in
the try block, and possibly information about the kind of operation and
the input value(s) triggering it, and catch would catch an object.
- Another way is to have a separate type for each possible exception.
- In C++ those could be merged using base and derived types.
For any of those, we should also define how to handle
implementation-defined exceptions; for example, PowerPC has half a dozen
specific kinds of invalid operation exceptions plus a general flag
combining them.
There are of course many variations but syntactically, so far it could
look like
try {
. . . block of code . . .
}
catch (FPException::Overflow fpexception) { /* overflow handler */ . . .
}
#ifdef PPC
catch (FPException::PowerPC_SignalingNaN fpexception) { /* SNaN handler
*/ . . . }
catch (FPException::PowerPC_InvalidConversion fpexception) { /* Invalid
Conversion handler */ . . . }
catch (FPException::PowerPC_SqrtOfNegative fpexception) { /* Sqrt of
Negative handler */ . . . }
#endif
catch (FPException::InvalidOperation fpexception) { /* General Invalid
Operation handler */ . . . }
catch (FPException::ZeroDivide fpexception) { /* Divide Finite by Zero
handler */ . . . }
catch (int m) { /* integer handler */ }
catch (...) { /* handler for anything else */ }
In each of the FPException catch clauses, the "fpexception" is like a
function parameter containing the exception information, is optional, and
can be any name you choose.
A catch clause can have a list of exception types if they all need the
same handling.
This is only part of the solution. One issue is how the exceptions to
check are to be specified.
The rule could be that the floating-point exceptions to be checked for
would be those which have a catch clause naming them, but that's not true
for general C++ exceptions so would be an inconsistency. A portable way
to specify which ones to enable would be useful; for example it could be a
function like
FPEnable oldcontrols = enableFPExceptions (FPEnable::Overflow |
FPEnable::InvalidOperation | FPEnable::ZeroDivide);
which sets up exception checking controls and returns the old exception
controls, along with another function to restore the saved controls
afterwards
restoreFPExceptions (oldcontrols);
Since a catch handler doesn't have access to the try block's local
variables, those would have to be outside the try block. They could be
useful elsewhere too.
In C++ an alternative would be that the control setting would construct an
object whose destructor would automatically do the restore (although that
wouldn't work for C which doesn't have constructors and destructors), eg,
{
FPEnableExceptions oldcontrols (FPEnable::Overflow |
FPEnable::InvalidOperation | FPEnable::ZeroDivide);
try . . .
// At the end of this block the destructor
FPEnableExceptions::~FPEnableExceptions (oldcontrols) would be run,
// restoring the old controls.
}
Assuming the first way (because it's more compatible with C), the
combination (with the int and ... deleted) is
FPExceptionControls oldcontrols = enableFPExceptions (FPEnable::Overflow
| FPEnable::InvalidOperation | FPEnable::ZeroDivide);
try {
. . . block of code . . .
}
catch (FPException::Overflow fpexception) { /* overflow handler */ . . .
}
#ifdef PPC
catch (FPException::PowerPC_SignalingNaN fpexception) { /* SNaN handler
*/ . . . }
catch (FPException::PowerPC_InvalidConversion fpexception) { /* Invalid
Conversion handler */ . . . }
catch (FPException::PowerPC_SqrtOfNegative fpexception) { /* Sqrt of
Negative handler */ . . . }
#endif
catch (FPException::InvalidOperation fpexception) { /* General Invalid
Operation handler */ . . . }
catch (FPException::ZeroDivide fpexception) { /* Divide Finite by Zero
handler */ . . . }
restoreFPExceptions (oldcontrols);
What about C? C doesn't have try, throw or catch, and doesn't have
classes so the "::" syntax wouldn't work, but possibly could have
something like:
fpexceptioncontrols oldcontrols = enablefpexceptions
(fpexception_overflow | fpexception_invalidoperation |
fpexception_zerodivide);
try {
. . . block of code . . .
}
catch (fpexception_overflow fpexception) { /* overflow handler */ . . .
}
#ifdef PPC
catch (fpexception_powerpc_signalingnan fpexception) { /* SNaN handler
*/ . . . }
catch (fpexception_powerpc_invalidconversion fpexception) { /* Invalid
Conversion handler */ . . . }
catch (fpexception_powerpc_sqrtofnegative fpexception) { /* Sqrt of
Negative handler */ . . . }
#endif
catch (fpexception_invalidoperation fpexception) { /* General Invalid
Operation handler */ . . . }
catch (fpexception_zerodivide fpexception) { /* Divide Finite by Zero
handler */ . . . }
restorefpexceptions (oldcontrols);
A simpler example to just handle overflow would be
fpcontrols oldcontrols = enablefpexceptions (fpexception_overflow);
try {
. . . block of code . . .
}
catch (fpexception_overflow fpexception) { /* overflow handler */ . . .
}
restorefpexceptions (oldcontrols);
It's more C than C++ style, but should work in C++ too. It doesn't look
much different from the proposal below.
>From an implementation point of view, the same approaches and the same
performance issues apply as in my earlier email. Optimizations like
saving and setting then later restoring exception controls can be moved
out of loops to reduce overhead.
This doesn't handle automatic value substitution, and like some of our
other approaches is a heavy approach where block of code is a simple
expression, but to me it seems fairly readable.
If C ever wanted to extend exception handling to allow throws, this is
compatible with the C++ syntax and semantics. If C and/or C++ ever wanted
to extend exception handling to handle traps, other hardware detected
events, or operating system detected events, those could be extensions of
this.
- Ian McIntosh IBM Canada Lab Compiler Back End Support
and Development
David Hough CFP ---2014-05-29 04:37:24 PM---Unlike normal C++ try blocks
which can be compiled without reference to whatever exceptions might be
From:
David Hough CFP <pcfp at oakapple.net>
To:
cfp-interest at ucbtest.org,
Date:
2014-05-29 04:37 PM
Subject:
[Cfp-interest] more on try/catch
Sent by:
cfp-interest-bounces at oakapple.net
Unlike normal C++ try blocks which can be compiled without reference to
whatever exceptions might be caught, floating-point try blocks have to
be compiled knowing what exceptions might be singled out for special
treatment.
So maybe fp try/catch
should just be separated syntactically as
well as semantically from C++:
fe_try {
}
fe_catch_sub( e, elist) {
}
fe_catch_exceps( e, elist) {
}
fe_catch_flags( f, flist) {
}
I've added a new wrinkle - fe_catch_sub which computes a substituted
value and continues execution. How is the substituted value evaluated?
It's the value of a compound statement - but it's undefined (and compilers
ought to warn) if it uses any variables whose values change within the
try block. Thus the try block to use with the substituted value
is probably pretty small. The substituted value can be presubstituted
if there's system support for that, but in the much more likely event that
there isn't, then the compiler has to generate appropriate tests and
branches.
The elist usually better be a list of one subexception of invalid
rather than invalid itself;
otherwise the compiler has to generate tests wherever a signaling NaN
might
cause an invalid exception. Do we need a nonstandard pragma (meaning
OK to ignore) that says compiler need not worry about signaling NaNs in a
given scope? Life would have been a lot simpler if signaling NaNs had
been given their own exception in 1977.
The substitute-exor feature of 754-2008 can be provided by the above plus
a standard function fe_exor_result(x,y,z) which returns abs(x) with the
exor signs of y and z.
_______________________________________________
Cfp-interest mailing list
Cfp-interest at oakapple.net
http://mailman.oakapple.net/mailman/listinfo/cfp-interest
_______________________________________________
Cfp-interest mailing list
Cfp-interest at oakapple.net
http://mailman.oakapple.net/mailman/listinfo/cfp-interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0001.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 105 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0011.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0012.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0013.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0014.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0015.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0016.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0017.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0018.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0019.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0020.gif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 45 bytes
Desc: not available
Url : http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20140530/8234c247/attachment-0021.gif
More information about the Cfp-interest
mailing list