NCEG Generic Functions proposal

David Hough sun!Eng!David.Hough
Sat Sep 28 16:45:16 PDT 1991


The Numerical C Extensions Group is preparing a report of recommended
extensions for ANSI-C to render it more suitable for scientific computation.
The following proposes an extension to provide a facility like the generic
intrinsic function operators of Fortran-77.  Comments are welcome.  tbl |
troff -ms source is available from dghavalidgh.com.

Introduction

     The Numerical C Extensions Group is preparing a report of recommended
extensions for ANSI-C to render it more suitable for scientific computation.
My personal goal is to render the extended language at least as adequate as
Fortran-77 in all areas.

     The NCEG report is expected to contain a number of independent sections.
Pioneering implementations might choose to implement some or all of the sec-
tions.  Zortech has already incorporated some preliminary ideas from one of
the subgroups in a C compiler product for PC's.  My personal goal is to get
the language extensions defined, published, and implemented at least on a GCC
base before work begins on the next major revision of the ANSI-C Standard.

     The following proposes an extension to provide a facility like the gen-
eric intrinsic function operators of Fortran-77.  Text and Rationale sections
are intermixed.  No doubt there are many points in the text that could be
improved but I hope the intent is clear.

New Section 3.3.2.2.1: Generic Function Calls

     Constraints: The expression that denotes the called function shall be an
identifier that is a generic function designator.  The number of arguments
shall agree with the number of operands for that generic function.   Each
argument shall be of appropriate arithmetic type - integral, floating-point,
imaginary, or complex - according to the built-in prototype for that generic
function.

     Semantics: An generic function identifier followed by parentheses con-
taining a non-empty comma-separated list of expressions is a generic function
call.  The list of expressions specifies the arguments to the function.  In
preparing for the call to a function, the arguments are evaluated, and each
parameter is assigned the value of the corresponding argument.

     When the floating-point evaluation style "evaluate-to-narrowest-need" is
in effect, generic functions of one argument are evaluated in the type of that
argument; generic functions of more than one argument are evaluated in the
type of least precision and dimension to which all arguments can be promoted.
When the floating-point evaluation style "evaluate-to-widest-need" is in
effect, generic functions are evaluated in the type of the complete expres-
sion, widened if appropriate in the cases of assignment and function arguments
as described elsewhere.  Arguments to generic functions are not complete
expressions.

     In both expression evaluation modes, the precision of floating-point
expressions will be at least as high as the minimum precision currently speci-
fied.

     The order of evaluation of the arguments, and subexpressions within the
arguments is unspecified.

     If an exception occurs during the evaluation of a generic intrinsic func-
tion, the behavior is undefined except for implementations defining
  FPCE IEEE  ; see section 3.3.18.
--    -    --

     Rationale: See the proposal for IEEE extensions for discussions of
"evaluate-to-narrowest-need" vs. "evaluate-to-widest-need", "minimum evalua-
tion precision", and "complete expression".  See the proposal for complex
extensions for "dimension" and "imaginary" types; floating-point and imaginary
expressions must be promoted to complex types before they can be combined with
each other or with complex types.

Augmented section 3.5.1: Storage Class

     Augment the storage class syntax in 3.5.1 with:

storage-class-specifier:
          generic
        --       --
        ...

Semantics: The   generic   specifier is called a "storage-class specifier" for
               --       --
convenience only.  No type-specifiers, type-qualifiers or initializers are
permitted.  The following declarator must be an identifier-list.  Each iden-
tifier must be a generic function known to the implementation.

     Rationale:  Each compiler has a list of generic functions that it knows
about in the same sense that it knows about operators.  There is no need for
or means to declare generic function prototype parameters or function values.

     Rationale:  To preserve compatibility with existing code, the programmer
must explicitly inform the compiler that he wishes to use the common double
function identifiers as generic.  A standard header fpce math.h is defined for
                                                        -
convenient declaration.  Generic functions are like conventional arithmetic
operators in these respects:

1    The semantics are not specified in detail but rely on common mathematical
     understanding.

2    Exception handling is not specified.  Generic functions might set errno,
     and might not; high-performance implementations probably won't.

3    Generic function invocations do not bound complete expressions in
     evaluate-to-widest-need expression evaluation, unlike ordinary functions.

4    In conventional expression evaluation, the function evaluation type is
     determined by the types of the operands rather than by default argument
     promotions or by explicit prototypes.

5    Generic functions can't be passed as parameters or have their address
     taken.

     Alternatives: with the foregoing formulation, it is not possible to use
both the generic function and the conventional function of the same name in
the same program.   Another formulation would be to define the generic func-
tion names as   sqrt  ,   exp  , etc., so they could be used in that form
              --    --  --   --
without declaring them first, and in fpce math.h would be
                                         -

#undef sqrt
#define sqrt(X)   sqrt  (X)
                --    --

instead of

#undef sqrt
  generic   sqrt;
--       --

fpce math.h and math.h could then co-exist in the same program.
    -

New Section 3.3.18: Standard Generic Functions

     Rationale: It would be possible to build each generic function into the
syntax of the C language in the way that the arithmetic operators are.  I
don't believe that is worthwhile or as useful as enumerating them with their
permissible operands.

     Rationale: The list of standard functions will be contentious.  I recom-
mend the following as indicative of the intended scope but the exact composi-
tion of the list is the least important part of this proposal at this time.

     Each implementation shall recognize each of the following  generic  func-
tion identifiers:

Name        Args   Types   Definition

                           # from ANSI-C
acos          1        F   trig
asin          1        F   trig
atan          1        F   trig
ceil          1        F   integral part rounded up - exact
cos           1       FC   trig
cosh          1        F   trig
exp           1       FC   exponential
floor         1        F   integral part rounded down - exact
fmod          2       IF   remainder, same sign as first arg
log           1       FC   natural logarithm
pow           2      IFC   power
sin           1       FC   trig
sinh          1        F   trig
tan           1        F   trig
tanh          1        F   trig
sqrt          1      IFC   square root
                           # from Fortran-77
abs           1      IFC   absolute value or modulus
aint          1        F   integral part rounded toward zero - exact
anint         1        F   integral part bias rounded toward nearest - exact
conjg         1        C   complex conjugate
dim           2       IF   positive difference
max         >=1       IF   maximum
min         >=1       IF   minimum
                           # from IEEE 754
copysign      2       IF   copy sign bit
logb          1        F   exponent of radix
nextafter     2        F   next representable number
remainder     2       IF   remainder, minimum magnitude
scalb         2        F   scale by power of radix
                           # suggestions from various sources
arg           1      IFC   (complex) argument
arint         1        F   integral part bias rounded per current rounding direction - inexact
expm1         1        F   exp(x)-1
log1p         1        F   log(1+x)
mmax        >=1      IFC   maximum magnitude
mmin        >=1      IFC   minimum magnitude

Permitted argument types are indicated thus:

Letter   Permitted Types

  I      integral (signed and unsigned)
  F      floating-point (float, double, long double, long float if defined)
  C      integral, floating-point, imaginary, complex

Multivalued complex functions return principal values.

     aint,anint: In   FPCE  754   implementations, these functions do not
                    --    --   --
raise inexact.

     arg:  This function computes the argument of a complex number between -pi
and +pi, and eliminates the need for generic atan2. abs(complex) eliminates
the need for generic hypot.

     arint: In   FPCE 754   implementations, this function raises inexact when
               --    -   --
the result differs from the argument.

     fmod:  This function could be subsumed by extending the % operator to
permit floating-point operands.

     mmax,mmin:  mmax selects the argument with the largest magnitude.

     scalb:  A generic function as originally envisioned by IEEE 754 with both
arguments in floating-point format.

     For   FPCE IEEE   implementations, exceptional cases will be spelled out
         --    -    --
in complete detail.  It's not worth doing so until the list of standard gen-
eric functions is agreed.

     Rationale:  The proposal permits implementations to define other generic
intrinsic functions based on common mathematical understanding.  But program-
mers are not allowed to define their own generic intrinsic functions; that
raises too many issues best left for more ambitious languages.

New Section 4.14: <fpce math.h>
                       -

     This header file provides a convenient way to declare all the standard
generic functions.  The programmer replaces
#include <math.h>
with
#include <fpce math.h>
              -
Thus <math.h> declarations without generic function replacements: HUGE VAL,
                                                                      -
frexp, ldexp, modf, log10, and atan2 - have declarations in <fpce math.h>
                                                                 -
copied from those in ANSI-C <math.h>.

     Alternate:  In the alternate definition, #include <fpce math.h> would
                                                            -
follow #include <math.h> in programs that wished to exploit the list of stan-
dard generic functions, and so would only include identifiers that were rede-
fined.




More information about the Numeric-interest mailing list