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