* Document Number: WG14 N750/J11 97-113
C9X Revision Proposal
=====================
* Title: LIA-1 Binding: LIA-1 annex.
Author: Fred J. Tydeman
Author Affiliation: Tydeman Consulting
Postal Address: 3711 Del Robles Dr., Austin, Texas, USA, 78727
E-mail Address: tydeman@tybor.com
Telephone Number: +1 (512) 255-8696
Fax Number: +1 (512) 255-8696
Sponsor: WG14
Date: 1997-09-16
Proposal Category:
__ Editorial change/non-normative contribution
__ Correction
Y_ New feature
__ Addition to obsolescent feature list
__ Addition to Future Directions
__ Other (please specify) ______________________________
Area of Standard Affected:
__ Environment
Y_ Language
__ Preprocessor
__ Library
__ Macro/typedef/tag name
__ Function
__ Header
Y_ Other (please specify) Annex_________________________
Prior Art: Very little. Sun, and maybe others, print messages
at program termination if any IEC 559 flags are raised. That
is one small part of this proposal.
Target Audience: Programmers writing programs that perform a
significant amount of numeric processing.___________________
Related Documents (if any):
WG14/N758 C9X and LIA-1 informative annex,
WG14/N756 LIA-1 Binding: Arithmetic exception => SIGFPE,
WG14/N755 LIA-1 Binding: to ,
WG14/N753 LIA-1 Binding: Rationale,
WG14/N752 LIA-1 Binding: Optional parts annex,
WG14/N751 LIA-1 Binding: Combined LIA-1 + IEC-559 annex,
WG14/N749 LIA-1 Binding: ,
WG14/N748 LIA-1 Binding: Adding 'pole' from LIA-2,
WG14/N747 IEC 559 Binding: Signaling NaNs,
WG14/N528 C Binding for LIA-1,
WG14/N488 LIA-2 (math library),
WG14/N487 LIA-1 (arithmetic),
WG14/N486 LIA Overview,
WG14/N463 Impact of adding LIA-1,
WG14/N461 C Binding of LIA-1
Proposal Attached: _Y Yes __ No, but what's your interest?
Abstract: This part of the C9X+LIA binding discusses the
binding of LIA-1 to C, that is, what it takes to have a LIA-1
conformant implementation.
Proposal:
Note: The '*' characters in the lefthand column are not part
of the proposal (they are useful for emacs M-x outline mode)
In the following, **bold text**, *italic text*,
`code sample` are the conventions used to indicate
text different from normal.
* -- Add to 6.8.8 Predefined macro names:
The following macro name is defined if and only if the
implementation conforms to Annex H.
__STDC_LIA_1__ The decimal constant 1.
* -- Modify annex H Language Independent Arithmetic.
Either replace with or merge the following.
Annex H
(normative)
Language Independent Arithmetic
** H.1 Introduction
-Replace the introduction with:
This annex specifies C language support for the ISO/IEC
10967-1 language independent arithmetic (LIA-1) standard.
An implementation that defines __STDC_LIA_1__ conforms to
the specification in this annex. Where a binding between
the C language and LIA-1 is indicated, the LIA-1-specified
behavior is adopted by reference, unless stated otherwise.
An implementation shall conform to all the requirements of
LIA-1 (ISO 10967-1:1994) unless otherwise specified in this
clause.
LIA-1 specifies a parameterized model of arithmetic
computation. The purpose of LIA-1 is to provide a known
environment in conforming implementations across platforms
and languages for applications requiring numeric
computation. Overall, the C binding of LIA-1 doesn't affect
existing programs but new programs will achieve a higher
degree of portability on LIA-1 systems. The impact of the
changes are: adding some macros, adding a handful of library
functions, detecting arithmetic exceptions, and requiring
the implementation to document certain features of its
arithmetic.
-Replace LIA-1-like with LIA-1 throughout the annex.
** H.2 Types
*** H.2.2 Integral Types
-Replace no integer types conform with:
The C integral types **int**, **long**, **long
long**, **unsigned int**, **unsigned long**,
**unsigned long long** conform to LIA-1[footnote].
[footnote]: The conformity of **short** and **char**
(plain, signed or unsigned) is not relevant since values of
these types are promoted to **int** (plain, signed or
unsigned) before computations are done.
**** H.2.2.1 Integer Parameters
-Add another parameter:
modulo INT_OUT_OF_BOUNDS.
The parameter modulo is always true for the unsigned types,
and is not provided for those types. The parameter modulo
is true when INT_OUT_OF_BOUNDS is 1 (wrap) or false when
INT_OUT_OF_BOUNDS is 2 (notify) and covers all LIA-1
conformant signed types. The implementation picks the value
of modulo. It is implementation defined if the user can
change the value of modulo.
**** H.2.2.2 Integer Operations
-Add the following operations:
modaI modulo(x, y), lmodulo(x, y), llmodulo(x, y).
modpI No binding.
signI sgn(x), lsgn(x), llsgn(x).
*** H.2.3 Floating-Point Types
-Replace no floating-point types conform with:
The floating types **float**, **double**, and **long
double** conform to LIA-1.
**** H.2.3.1 Floating-Point Parameters
-Add some more parameters:
denorm FLT_SUBNORMAL, DBL_SUBNORMAL, LDBL_SUBNORMAL.
iec_559 FLT_IEC_559, DBL_IEC_559, LDBL_IEC_559.
The *_IEC_559 macros represent booleans and have values 1 or
0.
-Add some more derived constants:
fmin FLT_TRUE_MIN, DBL_TRUE_MIN, LDBL_TRUE_MIN.
rnd_error FLT_RND_ERR.
If *_SUBNORMAL is not 1, then *_TRUE_MIN is the same as
*_MIN.
The FLT_RND_ERR macro must be less than or equal to 1.0
Rounding error **FLT_RND_ERR** depends upon rounding mode
**FLT_ROUNDS**. Rounding error will be constant
expression suitable for use in **#if** if and only if
**FLT_ROUNDS** is constant.
**** H.2.3.2 Floating-Point Operations
-Add additional operations as functions:
signF fsgnf(x), fsgn(x), fsgnl(x).
fractionF fracrepf(x), fracrep(x), fracrepl(x).
succF fsuccf(x), fsucc(x), fsuccl(x).
predF fpredf(x), fpred(x), fprecl(x).
ulpF ulpf(x), ulp(x), ulpl(x).
truncF trunctof(x, n), truncto(x, n), trunctol(x, n).
roundF roundtof(x, n), roundto(x, n), roundtol(x, n).
*** H.2.4 Type Conversions
-Add the following macro calls:
cvtF->I icvt(x), lcvt(x), llcvt(x),
uicvt(x), ulcvt(x), ulcvt(x).
** H.3 Notification
**** H.3.1.1 Indicators
-Split the 'undefined' into undefined and pole for the
existing floating-point indicators.
-Add the following:
The following integer indicators shall be provided. They
shall be clear at the start of the program. They are set
when any arithmetic operation returns an exceptional value
as defined in LIA-1 clause 5. Once set, an indicator shall
be cleared only by explicit action of the program (that is,
they are sticky).
undefined INT_INVALID.
pole INT_DIVBYZERO.
integer_overflow INT_OVERFLOW.
Undefined covers zero/zero, while pole covers finite
non-zero/zero. For implementations that cannot distinguish
the two cases, pole is used. The macros
DISTINGUISH_INT_DIV_BY_ZERO and DISTINGUISH_FP_DIV_BY_ZERO
are the means to indicate if zero/zero can be distinguished
from finite non-zero/zero for integral types and floating-point
types respectively. The use of pole is a deviation from LIA-1.
The macro FP2INT_OF_LARGE is used, in place of INT_OVERFLOW
as required by LIA-1, to document how conversion of large
floating-point values to out-of-bounds integral values will
notify. FP2INT_OF_LARGE shall be either INT_OVERFLOW or
FE_INVALID.
For example, the LIA-1 indicator subset
{floating_overflow, underflow, integer_overflow}
would be denoted by the expression
FE_OVERFLOW | FE_UNDERFLOW | INT_OVERFLOW
The integer indicator interrogation and manipulation
operations are:
set_indicators ieraiseexcept(i).
clear_indicators ieclearexcept(i).
test_indicators ietestexcept(i).
current_indicators ietestexcept(INT_ALL_EXCEPT).
where i is an expression of type **int** representing a
LIA-1 indicator subset.
When notification via flags is chosen, then whenever a LIA-1
exceptional value would result, the appropriate indicator
shall be set (sometime before program accesses the status
flag or terminates) and an implementation defined
continuation value used.
At program termination, if any LIA-1 indicator is set:
- the implementation shall send an unambiguous and "hard to
ignore" message (see LIA-1 subclause 6.1.2) to stderr. The
message should identify the indicators set.
- next, the **stderr** stream shall then be flushed and
**stderr** closed. It is implementation defined if other
open output streams are flushed, other open streams closed,
and any files created by the **tmpfile** function are
removed.
- finally, control is returned to the host environment. An
implementation-defined form of the status *unsuccessful
termination* is returned.
**** H.3.1.2 Traps
Trap first exception and terminate shall include the
following.
When notification via traps is chosen, then whenever a LIA-1
exceptional value would result, the implementation shall
send a message to **stderr** (sometime before any other
output). The message sent to **stderr** should identify
the cause of the notification and the operation responsible.
Next, the **stderr** stream shall then be flushed and
**stderr** closed. It is implementation defined if other
open output streams are flushed, other open streams closed,
and any files created by the **tmpfile** function are removed.
Finally, control is returned to the host environment. An
implementation-defined form of the status *unsuccessful
termination* is returned.
*** H.3.2 User selection
The implementation shall provide a means for a user or
program to select among the alternative notification
mechanisms provided (see LIA-1 subclause 6.3). The
LIA_NOTIFY pragma is the method used. LIA_NOTIFY FLAGS and
LIA_NOTIFY TRAP are the LIA-1 required conformant
mechanisms. LIA_NOTIFY UNDEF and LIA_NOTIFY IGNORE are not
LIA-1 conformant.
** H.4
This subclause contains specification of facilities
that is required for LIA-1 implementations.
*** H.4.1 Nearest integer macros
The macros used to convert from floating-point types to
signed integral types are defined for out-of-bounds results
in both wrapping and trapping modes. The use of
FP2INT_OF_LARGE instead of INT_OVERFLOW is a deviation from
LIA-1.
**** **H.4.1.1 The icvt macro**
If the rounded value is outside the range of **int** and
**INT_OUT_OF_BOUNDS** is 1 (wrap), the rounded value is
wrapped modulo (**INT_MAX-INT_MIN+1**).
If the rounded value is outside the range of **int** and
**INT_OUT_OF_BOUNDS** is 2 (notify), the numeric result
is unspecified and **FP2INT_OF_LARGE** is raised.
**** **H.4.1.2 The lcvt macro**
If the rounded value is outside the range of **long** and
**INT_OUT_OF_BOUNDS** is 1 (wrap), the rounded value is
wrapped modulo (**LONG_MAX-LONG_MIN+1**).
If the rounded value is outside the range of **long** and
**INT_OUT_OF_BOUNDS** is 2 (notify), the numeric result
is unspecified and **FP2INT_OF_LARGE** is raised.
**** **H.4.1.3 The llcvt macro**
If the rounded value is outside the range of **long
long** and **INT_OUT_OF_BOUNDS** is 1 (wrap), the
rounded value is wrapped modulo
(**LLONG_MAX-LLONG_MIN+1**).
If the rounded value is outside the range of **long
long** and **INT_OUT_OF_BOUNDS** is 2 (notify), the
numeric result is unspecified and **FP2INT_OF_LARGE** is
raised.
*** H.4.2 Modulo functions
**** **H.4.2.1 The modulo function**
modulo(i,0) raises **INT_INVALID** and returns an
unspecified value
**** **H.4.2.2 The lmodulo function**
lmodulo(i,0) raises **INT_INVALID** and returns an
unspecified value
**** **H.4.2.3 The llmodulo function**
llmodulo(i,0) raises **INT_INVALID** and returns an
unspecified value