Expressions in initializers

Stephen Clamage steve at taumet.com
Sat Mar 9 01:33:07 AEST 1991


suhonen at kunto.jyu.fi (Timo Suhonen) writes:

>rjc at uk.ac.ed.cstr (Richard Caley) writes:

>   ct> You are assuming that the compiler knows what the function sqrt(double)
>   ct> does.  I think I've heard of a few that do.  Most don't.

>   Is it possible to know before the program is linked (run if you have
>   run time linking!). What stops me from defining my own sqrt?

>Doesn't ANSI standard let the compiler know the standard functions???
>If so, then sqrt(double) can be evaluated at compile time. And I
>think that is just what every compiler SHOUD do!

In Standard (ANSI/IOS) C, 'sqrt' is reserved for use as an external
identifier, and reserved for use as a file-level identifier if <math.h>
is included.  So consider the following C file (<math.h> NOT included):

	static double sqrt(double d) { return d / 2.0; }
	double x = sqrt(2.0);
	... and more stuff ...

If this were allowed and the compiler were to initialize x to 1.414...
it would be wrong to do so.  The correct initial value for x would be 1.0.

If <math.h> is included, the above is illegal, and the only interpretation
for sqrt() is the one in <math.h>.  So the compiler could evaluate
library functions with constant arguments when the appropriate headers
were included.  This starts getting a bit complicated, such as
	double x = sqrt((double)(srand(strlen("Hello")),rand()));
which could be evaluated at compile time if <math.h>, <stdlib.h>, and
<string.h> were all included.  No, wait, srand() should affect the
runtime environment, so we shouldn't evaluate this one at compile time.
Golly, it IS getting complicated.

Now consider cross-compilers.  We would have to execute library functions
for the target system on the host, using target system arithmetic, which
may have data type sizes and formats different from the host.

In the end, what have we saved by all this complication?  It seems unlikely
that initializing static variables is a large part of the execution time,
or that significant extra code space would be taken up.  If you have a
loop like
	while(...) { ...  x += sin(2.5); ...  }
you can save execution time by rewriting it as
	double sin25 = sin(2.5);
	while(...) { ...  x += sin25; ...  }
(This may give less accurate results on systems, but there are no
guarantees either way.)

You do lose notational convenience by not being able to say
	double sqrt2 = sqrt(2.0);
at the file level.  C++ does allow this notation, but it evaluates the
function calls at run time, conceptually before main() begins execution.
Thus, with my first example, the static version of sqrt() get called,
and with a less perverse program, the library sqrt() gets called.
-- 

Steve Clamage, TauMetric Corp, steve at taumet.com



More information about the Comp.lang.c mailing list