[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