[Cfp-interest] FE_EXCEPTIONAL simplifies alternate exception handling a lot
David Hough CFP
pcfp at oakapple.net
Tue May 13 16:35:53 PDT 2014
Here's the current:
----- ALTERNATE EXCEPTION HANDLING -----
standard pragmas do not afford all the flexibility needed to specify
alternate exception handling, so standard macros
FP_EXCEPTIONAL_DETERMINISTIC and FP_EXCEPTIONAL_NONDETERMINISTIC are defined
as well as a standard pragma, FENV_EXCEPT .
exceptions enumerated in ANSI-C 7.6:
FE_INEXACT
FE_UNDERFLOW
FE_OVERFLOW
FE_DIVBYZERO
FE_INVALID
FE_ALL_EXCEPT shorthand for all five
Add the following subexceptions of invalid and divbyzero:
subexception:
FE_INVALID_SNAN 7.2a
FE_INVALID_MUL 7.2b
FE_INVALID_FMA 7.2c
FE_INVALID_ADD 7.2d
FE_INVALID_DIV 7.2e
FE_INVALID_REM 7.2f
FE_INVALID_SQRT 7.2g
FE_INVALID_QUANTIZE 7.2h
FE_INVALID_INT 7.2i
FE_INVALID_UNORDERED 7.2j
FE_INVALID_LOGB 7.2k
FE_INVALID_OTHER especially for 754 chapter 9 functions
FE_DIVBYZERO_DIVISOR 7.3 divisor zero
FE_DIVBYZERO_LOGB 7.3 logb(0)
FE_DIVBYZERO_OTHER especially for 754 chapter 9 functions
#pragma STDC FENV_EXCEPT exception-list action
exception list is a list of exceptions and subexceptions
separated by commas
This pragma's actions don't change control flow:
DEFAULT 754 default
NO_FLAG default result, but no flag raised
MAY_FLAG implementation may raise flag or not
ABRUPT underflow only, mandatory
RECORD record the exception in a "debugger"
and continue; same as default if
no debugger active
What about functions invoked within compound statements controlled by
an alternate exception handling pragma? To follow the lead of
FENV_ROUND, a list of functions corresponding to 754 operations
specifies those affected by rounding and alternate exception handling pragmas.
Inlining does not affect whether an operation is affected.
Exceptional Macros
FE_EXCEPTIONAL_DETERMINISTIC(
expression or compound statement, exception1, exception2, ...)
FE_EXCEPTIONAL_NONDETERMINISTIC(
expression or compound statement, exception1, exception2, ...)
are special macros, almost varargs functions.
They evaluates the expression or compound statement,
and return a non-zero int if any of the listed exceptions arose in the
course of the computation, and a zero int otherwise.
The non-zero int might be an implementation-dependent encoding of the listed
exceptions that arose, taking into account sub-exceptions.
Flags and traps for the listed exceptions
are the same after execution as before.
FE_EXCEPTIONAL_DETERMINISTIC
finishes the expression or compound statement and then
sets the result value and continues execution.
FE_EXCEPTIONAL_NONDETERMINISTIC
is allowed to quit work on the expression or compound
statement as soon as it determines that a listed exception has occurred.
Intermediate results might not be in a consistent state. Listed exceptions
that might have been encountered later might not be reported.
Using the notation FE_EXCEPTIONAL to refer to either,
they are intended to be used like any other conditional expression,
if FE_EXCEPTIONAL(expr, exception) {
exceptional case code
} else {
nonexceptional case code
}
FE_EXCEPTIONAL(expr, exception) ? exceptional case code : nonexceptional case code
switch FE_EXCEPTIONAL(expr, exception) {
case ...
}
Since common usages would include
if FE_EXCEPTIONAL( expr, exception) {
exceptional case code
} else {
a = expr ;
}
FE_EXCEPTIONAL(expr, exception) ? exceptional case code : a = expr;
optimizing compilers would be expected to handle these cases
without unnecessary recomputation.
FE_EXCEPTIONAL is intended to impart the flexibility of C++ try/catch without
damaging C syntax or supporting the full generality of C++ try/catch.
FE_EXCEPTIONAL is not a function; its arguments can include a compound
statement and the expression or compound statement is not to be
evaluated outside the macro.
It seems much better to avoid scope issues by having
expressions and labels exist within normal
C syntax rather than somehow grafted onto pragmas.
We could note than a corresponding construct
FE_SIGNALING( expression or compound statement, signal1, signal2, ...)
could have commensurate benefits for non-numeric programs: hiding all
the complication of setting up, using, and tearing down local signal handlers
by making the compiler and operating system figure it out.
But that's not our case.
(By considering signals I came up with the name FE_SIGNALING and then
the name FE_EXCEPTIONAL, rather than FE_TRYCATCH,
but maybe somebody else has a better idea.)
More information about the Cfp-interest
mailing list