In programs compiled with the -Xt compilation option,
matherr
is invoked by functions in the math libraries when
errors are detected.
Note that matherr
is not invoked when the
-Xa and -Xc compilation options are
used
[see
cc(1)].
Users may define their own procedures for handling errors,
by defining their own function named
matherr
in their programs.
matherr
must be of the form described above.
When an error occurs,
a pointer to the exception structure
x
will be passed to the user-supplied
matherr
function.
This structure, which is defined in the
math.h header file, is as follows:
The element
type
is an integer describing the type of error that has occurred, from the
following list of constants (defined in the header file):
DOMAIN
argument domain error
SING
argument singularity
OVERFLOW
overflow range error
UNDERFLOW
underflow range error
TLOSS
total loss of significance
PLOSS
partial loss of significance
The element
name
points to a string containing
the name of the function that incurred the error.
The variables
arg1
and
arg2
are the arguments with which the function was invoked.
retval
is set to the default value that will be returned by the function
unless the user's
matherr
sets it to a different value.
If the user's
matherr
function returns non-zero,
no error message will be printed,
and
errno
will not be set.
If
matherr
is not supplied by the user,
the default error-handling procedures, described with
the math functions involved, will be invoked upon error.
These procedures are also summarized in the table below.
In every case,
errno
is set to
EDOM
or
ERANGE
and the program continues.
Default Error Handling Procedures
Types of Errors
type
DOMAIN
SING
OVERFLOW
UNDERFLOW
TLOSS
PLOSS
errno
EDOM
EDOM
ERANGE
ERANGE
ERANGE
ERANGE
ALL FUNCTIONS:
(any arg = NaN)*
M, N
-
-
-
-
-
BESSEL:
-
-
-
-
M, 0
-
y0, y1, yn (arg 0)
M, -H
-
-
-
-
-
EXP, EXPF:
-
-
H
0
-
-
LOG, LOG10:
LOGF, LOG10F:
(arg < 0)
M, -H
-
-
-
-
-
(arg = 0)
M, -H
-
-
-
-
-
POW, POWF:
-
-
±H
0
-
-
neg ** non-int
M, 0
-
-
-
-
-
0 ** non-pos
M, 0
-
-
-
-
-
SQRT, SQRTF:
M, 0
-
-
-
-
-
FMOD, FMODF:
(arg2 = 0)
M, X
-
-
-
-
-
REMAINDER:
(arg2 = 0)
M, N
-
-
-
-
-
GAMMA, LGAMMA:
-
M, H
H
-
-
-
HYPOT:
-
-
H
-
-
-
SINH, SINHF:
-
-
±H
-
-
-
COSH, COSHF:
-
-
H
-
-
-
ASIN, ACOS, ATAN2:
ASINF, ACOSF, ATAN2F:
M, 0
-
-
-
-
-
SIN, COS, TAN:
SINF, COSF, TANF:
(arg = ±)
M, 0
-
-
-
-
-
ACOSH:
M, N
-
-
-
-
-
ATANH:
(| arg| > 1)
M, N
-
-
-
-
-
(| arg| = 1)
-
M, N
-
-
-
-
* Except for pow(NaN,0), powf(NaN,0),
hypot(NaN,±) or hypot(±,NaN).
Abbreviations
M
Message is printed.
H
Value that compares equal to HUGE is returned
-H
Value that compares equal to -HUGE is returned
±H
Value that compares equal to HUGE or -HUGE is returned.
0
0 is returned.
X
arg1 is returned.
N
NaN is returned.
Usage
The following definition of a matherr function performs
some special case error handling:
int
matherr(register struct exception *x);
{
switch (x->type) {
case DOMAIN:
/* change sqrt to return sqrt(-arg1), not 0 */
if (!strcmp(x->name, "sqrt")) {
x->retval = sqrt(-x->arg1);
return (0); /* print message and set errno */
}
case SING:
/* all other domain or sing errors, print message */
/* and abort */
fprintf(stderr, "domain error in %s\n", x->name);
abort( );
case TLOSS:
/* print detailed error message */
fprintf(stderr, "loss of significance in %s(%g)=%g\n",
x->name, x->arg1, x->retval);
return (1); /* take no other action */
}
return (0); /* all other errors, execute default procedure */
}