[Cfp-interest] updated syntax.txt

David Hough CFP pcfp at oakapple.net
Wed Jun 11 14:25:13 PDT 2014


I've updated http://www.validlab.com/cfp/
with more recent versions of syntax.txt and exception-1985.txt

Here are the diffs for syntax.txt, the draft syntax discussion for the C
committee, to help you decide whether to look more closely.
After the diffs is the text itself.

DIFFS:

------- syntax.txt -------
43,44c43
< PowerPC can exploit its unconventional conditional branch instructions
< to detect exceptions.
---
> PowerPC can branch conditionally on floating-point exceptions.
52,53c51,52
< catch (floating-point exception-list 1) {
<  exceptional cases 1 code...
---
> catch (floating-point exception1) {
>  exceptional case 1 code...
55,56c54,55
< catch (floating-point exception-list 2) {
<  exceptional cases 2 code...
---
> catch (floating-point exception2) {
>  exceptional case 2 code...
60c59,60
< The normal case code is executed; if any of the exceptions in the list arises,
---
> The normal case code is executed; if any of the exceptions specified in
> catch clauses arises,
66,70c66,67
< Note that exception-list might contain more than one exception, such
< as FE_OVERFLOW|FE_UNDERFLOW if both are to be handled by the same code,
< though typically there is only one exception in the list.
< Also note that there might be more than one catch clause to catch more than
< one group of exceptions to be handled differently,
---
> Note that there might be more than one catch clause to catch more than
> one group of exceptions to be handled,
72a70,75
> One could extend the syntax to allow a list of exceptions as parameters
> of the catch keyword: in some applications FE_UNDERFLOW and FE_OVERFLOW
> are handled together to invoke a scaling version of the normal case code;
> in other applications FE_INVALID, FE_DIVISIONBYZERO and FE_OVERFLOW are
> handled together as errors,
> perhaps by breaking to a higher level or perhaps by aborting altogether.
75c78
< matlab.
---
> and matlab.
96c99
< if no alternate treatment is called out in a catch clause.
---
> if no alternate treatment is specified in a catch clause.
114,119c117,124
< compiler that could not exploit hardware traps would not be able to
< implement alternate exception handling fully and efficiently - it would
< have to test exception flags at the end of the try clause, and rely
< on the programmer to code in such a way that no expensive or infinite
< loop arises in the try clause if an exception arises.
< Furthermore, a little-appreciated but important requirement of 754-1985
---
> compiler would have to exploit hardware traps in order to
> implement alternate exception handling fully and efficiently.
> Otherwise by only testing
> exception flags at the end of the try clause,
> such a compiler would not be able to promptly terminate an exceptional
> loop until it had perhaps run for a long time or infinitely.
> Nor could it properly test for the underflow exception:
> a little-appreciated but important requirement of 754-1985
125,127c130,137
< The point of this very long preamble is that, syntactically,  the catch
< clause for floating-point exceptions should be seen before the try clause
< rather than afterward as it is in most languages.    One can imagine
---
> Thus syntactically,  a compiler might prefer that the catch
> clause for floating-point exceptions be seen before the try clause
> rather than afterward, as it is in most languages.    However
> the conventional try/catch paradigm properly puts the normal case first
> syntactically, for the benefit of the programmer who writes and the
> programmer who reads the code and must understand the normal case before
> delving into the exceptional case.
> One can imagine
131c141
< catch_fe( exception-list) {
---
> catch_fe( exception ) {
141c151
< catch_fe( exception-list) {
---
> catch_fe( exception ) {
147,161d156
< or allowing an optional red-flag pragma to warn one-pass compilers:
<
< try {
< #pragma STDC FENV_CATCH_AHEAD exception-list
<  normal case code...
< }
< catch_fe (floating-point exception-list) {
<  exceptional case code...
< }
<
< Compilers that would process the catch_fe clauses before generating the
< try clause code could ignore that pragma.
< One-pass compilers that encountered discrepancies in catch_fe clauses
< from the exceptions flagged in advance should probably generate errors.
<
178a174
>  normal case code...
180c176
< #pragma STDC FENV_CATCH exception-list
---
> #pragma STDC FENV_CATCH exception
183d178
<  normal case code...
186c181
< It's exactly the same try/catch semantics as what we started with,
---
> It's exactly the same try/catch semantics that we started with,




And here is the whole text:



Alternate Exception Handling Syntax


How fast you can drive a car depends on how fast you can stop


Alternate Exception Handling is specified in Chapter 8 of IEEE 754-2008.
It's a series of recommendations to programming environments about what
kinds of facilities to provide in languages for portable numeric 
programming.      Some of these recommendations have to do with changes
of control flow, and the best syntax to propose for these is the subject
of this note.

The overall idea is that the normal case should go as fast as possible
for performance reasons, so testing for exceptional conditions should not
slow it down.    Likewise the normal case should terminate as quickly as
possible when exceptional conditions arise, lest (particularly in a loop
terminated by a floating-point conditional test) it get into an expensive
or infinite loop.

The previous IEEE 754-1985 recommended traps on exceptions.    These are
implemented in most IEEE 754 hardware systems, but they are so low level
that they are not used
much except for debugging, where they can be easily used to stop the 
program altogether.    It is not possible to write portable code to
handle a hardware trap and continue in any useful way.    
But if free testing for exceptions is built into the hardware without
slowing down the normal case, how can we make it available to the application
programmer?

Thus 754-2008
recommends alternate exception handling at a level that is meaningful
to the application programmer, leaving the details of hardware trapping
to the compiler, run time library, and operating system.     It is also
possible to implement 754-2008 alternate exception handling without hardware
traps, but that might entail significant performance penalties for either 
the normal case or exceptional case.     Exceptions can be detected
inline for each operation with tests on operands and results and flags -
slowing down the normal case - or at the end of the try clause with flags -
slowing the detection of the exceptional case (but testing flags alone does
not detect exact underflow exceptions).    Instead of traps,
some existing hardware such as
PowerPC can branch conditionally on floating-point exceptions.

The general programming paradigm as it might be naturally
expressed in many languages is

try {
 normal case code...
}
catch (floating-point exception1) {
 exceptional case 1 code...
}
catch (floating-point exception2) {
 exceptional case 2 code...
}
 following code...

The normal case code is executed; if any of the exceptions specified in
catch clauses arises,
the normal case code is interrupted as quickly as possible (and thus its
output variables may be in an indeterminate state) and the corresponding
exceptional case code is executed.      
In either case, after the normal case terminates
normally or the exceptional case terminates, the "following code" is executed.
Note that there might be more than one catch clause to catch more than
one group of exceptions to be handled,
though typically there is only one catch clause;
the examples that follow show only one but there could be more.
One could extend the syntax to allow a list of exceptions as parameters
of the catch keyword: in some applications FE_UNDERFLOW and FE_OVERFLOW
are handled together to invoke a scaling version of the normal case code;
in other applications FE_INVALID, FE_DIVISIONBYZERO and FE_OVERFLOW are
handled together as errors, 
perhaps by breaking to a higher level or perhaps by aborting altogether.

There are versions of try/catch in standard C++, java, C#, perl, php, python,
and matlab. 
There are try/catch extensions in at least two Fortran compilers 
targeting .NET applications.
These are all very similar but each slightly different.    

ruby has a somewhat
more different version; any begin/end compound statement may have one or
more rescue clauses corresponding to catch; there is no explicit try keyword.

Naturally, for C, the closest analog is C++.    
C++ catch clauses have as
arguments a parameter and its type.     The parameter is set by the system
for standard exceptions and by the programmer for programmer-defined exceptions
generated with the throw() function; the catch clause is matched to the
throw by the type of the thrown object.     There is also a catch(...)
syntax to catch all unspecified exceptions.

Unlike most of the exceptions for which try/catch was designed, some 
floating-point exceptions arise frequently - inexact especially and 
underflow in some programs - and the default treatment of continuing
execution with a prescribed result and raising a flag should be in force
if no alternate treatment is specified in a catch clause.

Thus several aspects of C++ exception handling are not needed to support 
754-2008 floating-point alternate exception handling:
 * no need to throw()
 * no need to catch(...) unspecified exceptions
 * catch clause is matched by exception rather than type -
   in standard C, exceptions receive names in <fenv.h> like FE_INVALID

Furthermore there is another difference important for performance:
whereas in C++ the code in the try clause is compiled without reference 
to subsequent catch clauses, for floating-point purposes it is usually
desirable or necessary to know which exceptions are to be trapped.
If the implementation is to be by traps, a trap handler has to be set
up before the try clause and torn down on exit; if the implementation
is to be by conditional branches on operands and results, that code
has to be generated inline in the try clause.     As a consequence,
a strictly one-pass C
compiler would have to exploit hardware traps in order to
implement alternate exception handling fully and efficiently.
Otherwise by only testing
exception flags at the end of the try clause,
such a compiler would not be able to promptly terminate an exceptional
loop until it had perhaps run for a long time or infinitely.
Nor could it properly test for the underflow exception:
a little-appreciated but important requirement of 754-1985
and 754-2008 is that exact underflow conditions must be detected by
trapping (1985) or alternate exception handling (2008) 
if enabled, even though the underflow flag is not raised (and thus can't be
used to detect exact underflow).

Thus syntactically,  a compiler might prefer that the catch
clause for floating-point exceptions be seen before the try clause
rather than afterward, as it is in most languages.    However
the conventional try/catch paradigm properly puts the normal case first
syntactically, for the benefit of the programmer who writes and the
programmer who reads the code and must understand the normal case before
delving into the exceptional case.
One can imagine
having the catch before, in which case the keyword should perhaps be
different:

catch_fe( exception ) {
 exceptional case code...
}
try {
 normal case code...
}

or having it within the try clause:

try {
catch_fe( exception ) {
 exceptional case code...
}
 normal case code...
}

One result of preserving some form of try/catch syntax is that 
floating-point
exception handling could be added to C++ with less syntactic 
effort than other possible approaches, and most of
C++ exception handling could be added to C with less syntactic 
effort than other possible approaches.
If that compatibility were deemed to cost more than its benefit,
then there are other alternatives.


First, since the explicit try clause is not really needed, one could
define catch_fe clauses for any compound statement delimited by curly
brackets, and instead of adding a catch_fe keyword, it could be a 
variety of pragma:


{
 normal case code...
{
#pragma STDC FENV_CATCH exception 
 exceptional case code...
}
}

It's exactly the same try/catch semantics that we started with, 
but in syntax not particularly close to C++ or anybody else's try/catch.
However it does match other #pragma's 
having scope in compound statements or in files,
that are already in C,
or are already in
previous floating-point extension reports going through the approval
process, or that are being considered to control other aspects
of floating-point code generation.


While the C floating-point extensions discussion group could pursue any of
these directions and report the results to the C committee,
we'd appreciate early feedback and direction from the C committee
as to which seems the most acceptable, or whether there's some better
C-like way to express the semantics.    The semantic content is pretty
much the same with all, but the syntax possibilities vary widely.



More information about the Cfp-interest mailing list