No generic intrinsic functions in ANSI-C
David Hough
sun!Eng!David.Hough
Mon May 13 11:13:45 PDT 1991
I got four responses to my questions on this topic about a month ago.
There was some disagreement about a number of details which makes me
uneasy about advocating any implementation radically different
from convention: the difference between "unconventional" and "nonstandard"
may be commercially insignificant. What is commercially significant is
passing the validation suites of various third parties, and arguing with
those parties about whether their validation tests correctly reflect a
standard has never proven profitable in the past. Sort of like turning
in a paper in college that is more subtle or obscure
than the reader is willing or able to deal with - it might as well be wrong.
Anyway here's some of my inquiries and conclusions so far:
A HOSTED ANSI-C compiler may treat the FUNCTION
identifiers defined in the Library
Chapter 4 as reserved words having the specified semantics without
regard to whether a function prototype or any other user-supplied
EXTERNAL PROTOTYPE is in scope.
This seems to be true, with the capitalized portions properly understood.
HOSTED environments are optional as opposed to freestanding environments
which have no reserved externals because those libraries may not have been
compiled yet.
FUNCTION identifiers
excludes macro definitions and typedefs which also may appear
in header files.
EXTERNAL PROTOTYPE implies that local static function and other definitions
can locally override the normally predefined library function identifiers.
The presence or absence of e.g. #undef exp doesn't appear to affect the
foregoing.
The catch, however, is in the phrase "the specified semantics" particularly
because of exception handling.
So in the following,
assume a hosted environment and no local static definitions.
printf(" xyz ...", p1, p2, p3, ...) MUST be recognized by the compiler
and the right thing done (for instance checking correspondence of
parameters to formats) whether or not a prototype is in scope,
even in the case where the varargs calling sequence is different
from the normal one.
True, because printf is a defined standard library function.
But if the varargs calling sequence is different from the normal one,
user-defined varargs functions
will not work unless a proper varargs prototype is in view at every
point where the function is invoked.
True because user-defined varargs functions are not defined standard library
functions.
In the following, "exp" replaced "sqrt" to sharpen the issues of error
detection; assume float < double < long double in precision and range.
exp(expression) can be recognized by the compiler and appropriate
code generated to return a value of the same type as the expression.
Can exp(float) return a float?
Can exp(long double) return a long double?
Can exp(int) return an int?
Is the reservation of expf and expl for future use superfluous?
Not much agreement about this. For instance in the case
doublevar = exp(floatvar);
using "expf" instead of "exp" probably would not
demonstrate the required errno
ERANGE behavior. I suppose you could define expf to only generate ERANGE
errors for argument values for which exp would overflow as well, but then the
behavior of expf would be a little odd and probably would not satisfy any
future standard which specified expf. The same kinds of problems afflict
doublevar = exp(longdoublevar);
using "expl" instead of "exp". The overflow would occur in the long double
to double conversion, probably a single instruction, and not in expl itself,
so ERANGE would not be set, unless expl set ERANGE whenever the double
function exp would overflow.
There might be more freedom with functions like sqrt and log because they
don't generate ERANGE errors, so funny business is harder to detect.
Aside from ERANGE, you generally can't tell what's going on because the
C standard doesn't constrain the accuracy of numerical functions - or simple
arithmetic - at all.
what effect does #undef exp have on subsequent interpretation of
"exp"? Suppose math.h is written
extern double exp(double);
#define exp(X) __generic_intrinsic_exp(X)
The #undef doesn't seem to affect any of the foregoing issues.
What should NCEG do? Depends on which priority is higher:
defining a language which is as numerically efficient as Fortran,
or defining a language which is completely compatible with ANSI-C (e.g.
no new reserved words). I know where my interests lie!
Persons recently added to this mailing list who want the full texts of the
opinions rendered on this subject should send email to dghaeng.sun.com
More information about the Numeric-interest
mailing list