[comp.lang.c] C vs. FORTRAN

jlg@beta.lanl.gov (Jim Giles) (06/22/88)

In article <3136@phoenix.Princeton.EDU>, mjschmel@phoenix.Princeton.EDU (Michael J. Schmelzer) writes:
> [...]
> Given that C produces assembly code very similar to the source
> code it came from, why should it be any slower than the object
> code generated by a FORTRAN compiler?

Who says that efficient object code needs to resemble the source very
much?  In fact, on pipelined machines, good object code always appears
quite confused compared to the source - all those code movement
optimizations.  Actually, even without pipelining, the object code
should be quite different - constant folding, common expression
elimination, strength reduction, and register allocation can all
rearrange the code quite a bit.  It may be true that many C compilers
produce object code that resembles source, but this is probably a
deficiency of those compilers.

> Furthermore, wouldn't optimizers eliminate any difference between
> their final products?

Depends on what type of optimization you're talking about.  The multi-
dimensioned array problems (which have seen so much recent discussion)
are hard for C to optimize because the language simple doesn't have
the dependency information available to it (not even in source).
Also, many C compilers throw out much of the dependency information at
an early stage in the compile process - no later optimization can get
it back.  Of course, the compiler could optimize anyway (by assuming
that no dependencies exist), but this would break code that really DID
contain dependencies.

Of course, C may have the reputation of being slow simply because the
compilers available to most people don't optimize very well.  Certainly
all the C compilers I've seen could stand some improvement (the famous
pcc - pessimizing C compiler, for example).

J. Giles
Los Alamos

eugene@pioneer.arpa (Eugene N. Miya) (06/23/88)

In article <3136@phoenix.Princeton.EDU> mjschmel@phoenix.Princeton.EDU (Michael J. Schmelzer) writes:
>Given that C produces assembly code very similar to the source
>code it came from, why should it be any slower than the object
>code generated by a FORTRAN compiler?
>
>Furthermore, wouldn't optimizers eliminate any difference between
>their final products?

My two yen:

Your fallacy is sort of based on the separation of parts in compilation
and an assumption from everything is performed properly: a common
misconception.  For instance, compilers appear as very monolith things
to most people (like me), only recently have companies started writing
compilers in high-level languages, started thinking about common code
generators for different languages, etc.  Sure, the binary machine
instructions all have to work in the machine instruction environment,
but many machines had different optimizers for their different language
compilers.  This is changing as common intermediate codes are
developing.  The point is things are changing for the better.  Consider
that supercomputer sometimes make terrible byte pushers [over
generalized].

In another case, we also tend to take a lot of features like
optimization for granted.  Most of these systems are poorly tested.
This is not completely the fault of manufacturers.  We ran un-vectorized
libraries month before we found the mistake, this was not a production
machine, a site configuration error.  In another case, I reserved
a big machine for stand alone use on micro-tasking research.  I was
expecting to see 4 CPU crunching a problem.  Only 1 was working.
The tasking package was distributed set up to only run on 1 CPU.
Only a stand alone test would have detected this problem.  TIme to
recompile.

Another gross generalization from

--eugene miya, NASA Ames Research Center, eugene@aurora.arc.nasa.gov
  resident cynic at the Rock of Ages Home for Retired Hackers:
  "Mailers?! HA!", "If my mail does not reach you, please accept my apology."
  {uunet,hplabs,ncar,decwrl,allegra,tektronix}!ames!aurora!eugene
  "Send mail, avoid follow-ups.  If enough, I'll summarize."

rwwetmore@watmath.waterloo.edu (Ross Wetmore) (06/28/88)

In article <3136@phoenix.Princeton.EDU> mjschmel@phoenix.Princeton.EDU (Michael J. Schmelzer) writes:
>Given that C produces assembly code very similar to the source
>code it came from, why should it be any slower than the object
>code generated by a FORTRAN compiler?
>
>What is missing from the equation here? I am currently writing
>programs in C and FORTRAN and thus have some interest in the matter.
>Mike Schmelzer mjschmel@phoenix!princeton.edu

  Part of the problem is that the presence or absence of certain
constructs in the high level language predisposes the programmer
towards a particular algorithm or coding style. Thus an algorithm
written in simple Fortran might be quite radically different than
one written in simple C.

  In C exponentiation is not an operator, but rather a function.
I have seen C programs where a for-loop has been used to avoid
doing a pow() function call or because simple integer exponentiation 
doesn't really exist. A Fortran programmer doesn't really think
and just uses '**' which usually just gets translated into an
appropriate function call by the compiler. The point is that the 
C programmer may produce a radically different program because of 
the different thought process required. The reverse happens when a
C concept like pointers is missing from the language.

  What is needed is a way to preprocess code or add compiler
extensions so that the expression of simple concepts can be done 
with simple high-level code and the implementation is left to the 
compiler. Even better is if the extensions can be added dynamically
by the programmer for his particular application, rather than 
rewriting the code to use a compiler which has the maximum overlap 
with his favorite set.

  For example a scientific application package might be a trivial
program in a language where a data types 'vector' and 'matrix'
existed with standard operators '+-*/' doing the appropriate thing.
Moreover if a new super-hardware device comes along to replace the
functions that presumably get called to do the actual work, then
the user need do very little more than recompile with a new compiler
switch or function library. This is far more preferable and less
time consuming than global changes to explicit programmer implement-
ation of the same functionality.

  Rather than converting Fortran to C, or Cobol, or PL/1, it might be
more worthwhile to look at some of the more flexible languages such
as C++ or ADA or their future incarnations. Hopefully, the relearning
cycle and upgrade path for these will be somewhat less steep after
the initial conversion, as the basic compiler is less liable to change,
but rather different packages of 'includes' will come along to provide
extensions and new features.

Ross W. Wetmore                 | rwwetmore@water.NetNorth
University of Waterloo          | rwwetmore@math.Uwaterloo.ca
Waterloo, Ontario N2L 3G1       | {uunet, ubc-vision, utcsri}
(519) 885-1211 ext 3491         |   !watmath!rwwetmore

jss@hector.UUCP (Jerry Schwarz) (06/29/88)

For those interested in the differences between C and FORTRAN with
regard to optimization I recommend

	Compiling C for Vectorization, Parallelization and Inline Expansion
	R. Allen and S. Johnson
	in Proceedings SIGPLAN '88  (SIGPLAN Notices July 88)
	pp. 241-249

The conference was last week.  The Notices should be arriving soon.

Jerry Schwarz
Bell Labs, Murray Hill

ok@quintus.uucp (Richard A. O'Keefe) (06/29/88)

In article <19633@watmath.waterloo.edu> rwwetmore@watmath.waterloo.edu (Ross Wetmore) writes:
>  In C exponentiation is not an operator, but rather a function.
>I have seen C programs where a for-loop has been used to avoid
>doing a pow() function call or because simple integer exponentiation 
>doesn't really exist. A Fortran programmer doesn't really think
>and just uses '**' which usually just gets translated into an
>appropriate function call by the compiler.

Not to knock either C or Fortran, but this may be a case where C is better
to use than Fortran.  Just because ** _looks_ like a simple operation (not
that different from *) doesn't mean that it isn't a call to a costly function.
I have seen published Fortran code where polynomials were evaluated with an
O(N * log(N)) algorithm (N being the degree of the polynomial) instead of an
O(N) algorithm, presumably because the programmer thought ** must be cheap.
If you have a program calculating X**N where N is an integer but is not in
the range -2..+3, take a very careful look at your program to see how it can
be improved.

smryan@garth.UUCP (Steven Ryan) (06/29/88)

>  Rather than converting Fortran to C, or Cobol, or PL/1, it might be
>more worthwhile to look at some of the more flexible languages such
>as C++ or ADA or their future incarnations. Hopefully, the relearning
>cycle and upgrade path for these will be somewhat less steep after
>the initial conversion, as the basic compiler is less liable to change,
>but rather different packages of 'includes' will come along to provide
>extensions and new features.

That was the idea behind Algol68, from twenty years back. I think Aad
was a bit ahead of time.

smryan@garth.UUCP (Steven Ryan) (06/29/88)

This should be the ten thousand article--sorry, couldn't resist it.

jlg@beta.lanl.gov (Jim Giles) (06/29/88)

In article <143@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes:
> [...]
> Not to knock either C or Fortran, but this may be a case where C is better
> to use than Fortran.  Just because ** _looks_ like a simple operation (not
> that different from *) doesn't mean that it isn't a call to a costly function.
> I have seen published Fortran code where polynomials were evaluated with an
> O(N * log(N)) algorithm (N being the degree of the polynomial) instead of an
> O(N) algorithm, presumably because the programmer thought ** must be cheap.
> [...]

The exponentiation operator isn't bad just because some people use it
badly.  Your example could have been coded just as badly with C (by using
the same algorithm and substituting function calls for the exponentiation
operator - it wouldn't be an intrinsic function if it wasn't cheap, would
it?).  If simple looking expressions should really be restricted to doing
only simple things, the C should not have macros (which can hide a lot
of complexity).

Also, Fortran doesn't _require_ a programmer to use **.  You could
code without it.  But, the exponentiation operator is an example of a
feature which allows the compiler to make optimizations without the
user having to sacrifice readability.  X**3 is more readable than
X*X*X (particularly is X is an expression).  X**3.5 is more readable
than EXP(3.5*LOG(X)).  The compiler automatically selects which
implementation to do, in general helping speed the code.  If you
always do pow(X,Y), the compiler has no choices to make.

The purpose of all higher level features of a language is to make it
easier for a _good_ programmer to do his job.  A feature which does
this should be considered for inclusion no matter how badly it _might_
be misused.  If the potential for misuse doesn't even result in
incorrect code (as in this case), then there is no reason not to
include the feature.

J. Giles
Los Alamos

ok@quintus.uucp (Richard A. O'Keefe) (06/30/88)

In article <20480@beta.lanl.gov> jlg@beta.lanl.gov (Jim Giles) writes:
>In article <143@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes:
>> Not to knock either C or Fortran, but this may be a case where C is better
>> to use than Fortran.

>The exponentiation operator isn't bad just because some people use it badly.

I didn't say that it was bad.  What I do say is that it is _MISLEADING_.
In C, for example, most of the operations for which there is special
syntax correspond to machine operations of similar cost.

What with prototypes and all, an ANSI C compiler is fully entitled to treat
	#include <math.h>
	double x;
	...
	x = pow(x, 3);
	x = pow(x, 3.5);
just the same as Fortran 77 would treat
	DOUBLE PRECISION X
	...
	X = X**3
	X = X**3.5
It is already the case on the UNIX systems where I've tried it that
	pow(x, (double)3)
uses the iterative method used for X**3.  (I personally don't think that
is a good thing, but that's another story.)

>X**3 is more readable than X*X*X (particularly is X is an expression).
pow(x,3) isn't _that_ hard to read, either.
>X**3.5 is more readable than EXP(3.5*LOG(X)).
True, but again, pow(x,3.5) isn't terribly hard to read, and in any
case the two expressions X**3.5 and EXP(3.5*LOG(X)) don't mean exactly
the same thing (may have different over/underflow conditions, yield
different results, &c).

>If you always do pow(X,Y), the compiler has no choices to make.
Misleading and soon to be wrong.  Misleading, because the run-time library
_does_ have some choices to make, and current libraries make them.  Soon
to be wrong, because ANSI C compilers are allowed to detect the standard
library functions and do special things with them.

>If the potential for misuse doesn't even result in incorrect code
>(as in this case), then there is no reason not to include the feature.

Well, ANSI C _does_ include the feature.  My point was simply that the
notation "pow(x, y)" _looks_ as though it might be costly, while the
notation "x ** y" _looks_ as though it is cheap and simple, and that
the first perception is the correct one, so that ANSI C's notation may
be better.  In fact it is _not_ the case in this example that the
misuse did not result in incorrect code.  Consider the two fragments:

C	Assume that N.ge.2		/* Assume that N >= 2 */
C	Fragment 1			/* Fragment 1 */
	T = A(1)			t = a[0];
	DO 10 I = 2,N			for (i = 1; i < n; i++) {
	   T = T + A(I) * X**(I-1)	    t += a[i]*pow(x, (double)i);
10	CONTINUE			}
C	Fragment 2			/* Fragment 2 */
	T = A(N)			t = a[N-1];
	DO 20 I = N-1,1,-1		for (i = n-2; i >= 0l i--) {
	    T = T*X + A(I)		    t = t*x + a[i];
20	CONTINUE			}

The two fragments are *not* equivalent.  It is easy to come up with an
example where fragment 2 correctly yields 1.0 and fragment 1 overflows.
{I am not asserting that fragment 2 is always the right thing to use!}

A good numeric programmer will use X**N __very__ seldom for other than
constant arguments.

What C _does_ lack that a numeric programmer might miss is a single-
precision version of pow().  Given
	float x, y, u, v;
	x = pow(u,v)/y;
it is not in general safe to evaluate pow(u,v) in single precision.
How much faster is float**float than double**double?
Sun-3/50 (-fsoft)	1.2
Sun-3/160 (-f68881)	2.5
Sequent (80387)		1.4
If this is typical (and I have no reason to expect that it is), the
lack of single precision elementary functions in C comes into the
"nuisance" category rather than the "major problem" one.  Since UNIX
systems often come with Fortran these days, and Fortran has single
precision elementary functions, it seems a pity not to let ANSI C
share them.

jlg@beta.lanl.gov (Jim Giles) (06/30/88)

In article <147@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes:
> [...]
> I didn't say that it was bad.  What I do say is that it is _MISLEADING_.
> In C, for example, most of the operations for which there is special
> syntax correspond to machine operations of similar cost.

It's not misleading.  It means what it says - exponentiation.  It looks
as expensive as an exponentiation operator - no more or less.  If the
syntactical appearance is what you mean by 'special syntax', why does
pow() look any more expensive than abs()?  Divide doesn't look all that
much more expensive than multiply either, but it is.
> 
> What with prototypes and all, an ANSI C compiler is fully entitled to treat
>    [example ...]
> just the same as Fortran 77 would treat
>    [other example ...]

Possibly true.  Also irrelevant.  You are making basically a syntactical
point. So the fact that the future versions of C will fix something
(that IT shouldn't have broke to begin with) is not relevant.

> [...]
> >X**3 is more readable than X*X*X (particularly is X is an expression).
> pow(x,3) isn't _that_ hard to read, either.
> >X**3.5 is more readable than EXP(3.5*LOG(X)).
> True, but again, pow(x,3.5) isn't terribly hard to read, and in any

LISP isn't terribly hard to read either, but it's not what I want to
code numerical expressions in.  The syntax that mathematics uses is
really well suited to the task.  The programming language syntax for
the same purposes should look as similar as possible to the original
math.  There is no reason that I can see to adopt any other rule of
choice in language design.

> case the two expressions X**3.5 and EXP(3.5*LOG(X)) don't mean exactly
> the same thing (may have different over/underflow conditions, yield
> different results, &c).

If X is in range, then LOG(X) is in range.  If X**3.5 is in range, then
certainly 3.5*LOG(X) is.  The expression given overflows (or underflows)
ONLY if the original numbers are out of range or if the final answer
is out of range.
> 
> >If you always do pow(X,Y), the compiler has no choices to make.
> Misleading and soon to be wrong.  Misleading, because the run-time library
> _does_ have some choices to make, and current libraries make them.  Soon

The choice I'm talking about is whether to cause a function call (the
most expensive of all the 'simple' operations).  Doesn't matter what the
subroutine library does, you've already made the expensive call.

> to be wrong, because ANSI C compilers are allowed to detect the standard
> library functions and do special things with them.

Fine, C is fixing something that shouldn't have been broken to begin with.
Now, if it would just add the operator ...

> [...]
> C	Assume that N.ge.2		/* Assume that N >= 2 */
> C	Fragment 1			/* Fragment 1 */
> 	T = A(1)			t = a[0];
> 	DO 10 I = 2,N			for (i = 1; i < n; i++) {
> 	   T = T + A(I) * X**(I-1)	    t += a[i]*pow(x, (double)i);
> 10	CONTINUE			}
> C	Fragment 2			/* Fragment 2 */
> 	T = A(N)			t = a[N-1];
> 	DO 20 I = N-1,1,-1		for (i = n-2; i >= 0l i--) {
> 	    T = T*X + A(I)		    t = t*x + a[i];
> 20	CONTINUE			}
> 
> The two fragments are *not* equivalent.  It is easy to come up with an
> example where fragment 2 correctly yields 1.0 and fragment 1 overflows.
> {I am not asserting that fragment 2 is always the right thing to use!}

An interesting example.  But it makes my point, not yours.  The first
fragment (in either language) looks expensive.  The C fragment also
looks harder to write and maintain - but no more expensive than the
Fortran fragment (this, of course, IS misleading, the C fragment is
probably slower).  Fragment 2 looks clearly preferable in either
language.  The existence of the exponentiation operator doesn't alter
my perceptions about these code fragments AT ALL.
> 
> A good numeric programmer will use X**N __very__ seldom for other than
> constant arguments.

Finally!  Something we agree upon.  But what does this have to do with
the value of placing the operator into the syntax?  Just because it's
seldom used for large or non-constant arguments, doesn't mean it needs
to be arcane or cryptic when it IS used.
> 
> What C _does_ lack that a numeric programmer might miss is a single-
> precision version of pow().  Given
> [...]
> How much faster is float**float than double**double?
> Sun-3/50 (-fsoft)	1.2
> Sun-3/160 (-f68881)	2.5
> Sequent (80387)		1.4
> If this is typical (and I have no reason to expect that it is), the
> [...]

For just multiplies, X*Y, the ratio on the Crays is about 60 (actually
that's an underestimate, since the single precision multiply can be
pipelined).  The ratio for exponentiation must be enormous!  Of course,
this would never be acceptable.  So the Cray C compiler uses SINGLE
instead of DOUBLE for all arithmetic.  I don't know if it even HAS
a way of doing real double.  (Cray single has ~14 decimal digits of
precision.)

My point is that if you're suggesting that languages should be designed
to protect a small number of naive users from making simple efficiency
errors - you're wrong.  Programming languages should be designed to
allow _good_ programmers to write and maintain their codes as productively
as possible.  After all, this is why C, with its terse (and sometimes
cryptic) syntax is so popular.  If you really want to protect naive
users, you should lobby for removal of expressions with side-effects
from C.

J. Giles
Los Alamos

dph@lanl.gov (David Huelsbeck) (07/01/88)

From article <20506@beta.lanl.gov>, by jlg@beta.lanl.gov (Jim Giles):
	[...]
> 
> LISP isn't terribly hard to read either, but it's not what I want to
> code numerical expressions in.  The syntax that mathematics uses is
                                                  ^^^^^^^^^^^
> really well suited to the task.  The programming language syntax for
> the same purposes should look as similar as possible to the original
> math.  There is no reason that I can see to adopt any other rule of
> choice in language design.
	[...]

Hmmm.

  Jim, I tend to think lisp looks more like mathematic syntax than 
Fortran does.  A small subset of Fortran looks a lot like arithmetic
but mathematics?  

I don't seem to remember seeing any DO loops in my mathematics texts.
Well, maybe in my numerical methods book but it also contained an
arithmetic-if-statement in an example of "good code".  Anybody who
can defend the AIS should have no problem with x+=(p=foo(b)?++i:i--)

I would have put a smile at the end but it might have looked like code. ;-D

If you want something that really looks like mathematics, with the 
the for-all and the there-exists operators, and REAL subscripting and
superscripting try MODCAP. (sigplan notices years ago)


> 
> 
> J. Giles
> Los Alamos

	David Huelsbeck
	dph@lanl.gov
	...!cmcl2!lanl!dph

news fodder
news fodder
news fodder
news fodder
news fodder
news fodder
news fodder
news fodder
news fodder
news fodder

nevin1@ihlpf.ATT.COM (00704a-Liber) (07/01/88)

In article <797@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:
|>Another possible plus for Fortran is that, by default (and for most
|>compilers, and in real F66 and F77, always) there is NO RECURSION,
|>and therefore no necessity of copying parameters to a stack. They
|>can be statically compiled in. This is only a benefit on some 
|>architectures.

What do you mean by 'statically compiled in'?  The references still need to
be copied; they (the references) are just copied to a fixed location
instead of to a relative position off the argument pointer (which points
into the stack).

|And no array allocation at run time. All arrays can be allocated in
|the compiler. All dope vectors except adjustable arrays are computable
|by the compiler.

Excluding dynamic arrays (arrays allocated in the heap), if you have a
stack, it takes ZERO more machine instructions to allocate arrays.  The
amount of space needed for a frame on the stack is determined at compile
time.
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				You are in a little twisting maze of
 /  / _ , __o  ____		 email paths, all different.
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah

nevin1@ihlpf.ATT.COM (00704a-Liber) (07/01/88)

In article <20506@beta.lanl.gov> jlg@beta.lanl.gov (Jim Giles) writes:

|LISP isn't terribly hard to read either, but it's not what I want to
|code numerical expressions in.  The syntax that mathematics uses is
|really well suited to the task.  The programming language syntax for
|the same purposes should look as similar as possible to the original
|math.  There is no reason that I can see to adopt any other rule of
|choice in language design.

Since when does 'x = x + 1' resemble anything besides an obviously false
statement in mathematics??  Also, since many of us use C for tasks other
than number crunching, does this mean that we should have NO desire for a
programming language to resemble mathematics?  Your reasoning is a little
faulty here.

|The choice I'm talking about is whether to cause a function call (the
|most expensive of all the 'simple' operations).  Doesn't matter what the
|subroutine library does, you've already made the expensive call.

A function call may not necessarily be made (can you say 'inlining').

|Fine, C is fixing something that shouldn't have been broken to begin with.

It was never broken (a little inefficient, but not broken).

|Finally!  Something we agree upon.  But what does this have to do with
|the value of placing the operator into the syntax?  Just because it's
|seldom used for large or non-constant arguments, doesn't mean it needs
|to be arcane or cryptic when it IS used.

If all the arguments are constant, what do you need a run-time operator
for?
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				You are in a little twisting maze of
 /  / _ , __o  ____		 email paths, all different.
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah

smryan@garth.UUCP (Steven Ryan) (07/02/88)

>|>and therefore no necessity of copying parameters to a stack. They
>|>can be statically compiled in. This is only a benefit on some 
>|>architectures.
>
>What do you mean by 'statically compiled in'?  The references still need to
>be copied; they (the references) are just copied to a fixed location
>instead of to a relative position off the argument pointer (which points
>into the stack).

Fortran argument list are sometimes assigned static memory by the compiler.
Except for arguments which are subscripted arrays, the compiler will know
the addresses of the will be put into the argument list (assuming variables
are staticcally allocated and not stack allocated). The overhead for passing
arguments is then computing expressions and stuffing away their values (same
for either language) and getting the parameter list address in the proper
register.

Any language which supports recursion must allocate local variables and
parameter lists on the stack. The address of variables must be computed
at runtime.

kannan@tut.cis.ohio-state.edu (Kannan Varadhan) (07/03/88)

Someone aeons ago, had mentioned there being a canonical collection of
the incompatabilities to be taken care of when calling FORTRAN
subroutines from C.

Does anyone have a copy of this that they could mail to me?

Thanks a lot,

KANNAN
-- 
email:  kannan@cis.ohio-state.edu	kannan@tut.cis.ohio-state.edu	       	 snail:  Kannan Varadhan 306, W. Lane Ave., # 15, Columbus, OH 43201 	        voice:  {Res.} (614) 297-8720 | {Off.} (614) 292-8234

======================================================================          Many that live deserve death.  And some that die deserve to live.  Can          you give it to them?  Then, do not be too eager to deal out death in            judgement, for even the very wise cannot see all ends.                                                    J R R TOLKIEN in "The Lord of the Rings" 	        ======================================================================

leo@philmds.UUCP (Leo de Wit) (07/03/88)

In article <852@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:
>>|>and therefore no necessity of copying parameters to a stack. They
>>|>can be statically compiled in. This is only a benefit on some 
>>|>architectures.
>>
>>What do you mean by 'statically compiled in'?  The references still need to
>>be copied; they (the references) are just copied to a fixed location
>>instead of to a relative position off the argument pointer (which points
>>into the stack).
>
>Fortran argument list are sometimes assigned static memory by the compiler.
>Except for arguments which are subscripted arrays, the compiler will know
>the addresses of the will be put into the argument list (assuming variables
>are staticcally allocated and not stack allocated). The overhead for passing
>arguments is then computing expressions and stuffing away their values (same
>for either language) and getting the parameter list address in the proper
>register.

The 'stuffing away of values' could well be more effective with stack 
addressing modes than with putting values in a static allocated list.
The stack modes do typically 'lower sp and put value at sp' (note: one
instruction) while the allocated lists need an offset (unless you load
the first address in an address register, but that's an instruction extra
compared to C; the sp needs not to be 'loaded').

How does FORTRAN b.t.w. handle the situation that there is a variable
arguments list (cf. printf()) ? Seems a bit difficult with 'static lists'.
Probably does not....

>
>Any language which supports recursion must allocate local variables and
>parameter lists on the stack. The address of variables must be computed
>at runtime.

So for static and 'static parameter list' variables. Even if you load
a register with the base of the list, you address the variables in it
relative to this base. That is as much computation as addressing relative
a frame pointer. On a paging system it may even take more, as the stack
pages are more likely to be in core than data pages - although a stack
pointer may behave weird, it will generally move in a relative small area.

                      Leo.

g-rh@cca.CCA.COM (Richard Harter) (07/04/88)

In article <546@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:

>So for static and 'static parameter list' variables. Even if you load
>a register with the base of the list, you address the variables in it
>relative to this base. That is as much computation as addressing relative
>a frame pointer. On a paging system it may even take more, as the stack
>pages are more likely to be in core than data pages - although a stack
>pointer may behave weird, it will generally move in a relative small area.

	I'm not sure I'm following this argument (or that it should be
followed) but when has that ever stopped anyone.  Arguments about efficiency
of different schemes are affected by how the hardware works.  In general,
however, a static area calling sequence scheme will be more efficient than
a stack scheme because the dirty work is done at link time rather than at
execution time.  Attend:

	Normally the important cost is the cost of referring to calling
sequence parameters within the body of code, and not the cost of loading
the parameters into the transfer area.  Consider the following pseudo code:

	procedure foo:
	parameters:
		declare a some_type;
	executable body:
		....
		a <- a + 1;
		...
	end foo:

Now, in a stack implementation, each reference to 'a' is of the form

contents(fixed_offset + stack pointer)

In a static are implementation the compiler generates a nominal absolute
address for 'a' relative to the data space for the routine.  The linker
replaces this by a nominal absolute address for 'a' relative to the data
space for the linked program.  The loader replaces this by an absolute
address.  The upshot of this is that when 'a' each reference to 'a' is
of the form

contents(fixed address)

It doesn't necesarily work this way -- it is all a matter of how the system
is set up.  But, given the supporting cast, static area calling sequences
can be treated as globals.  In many machines absolute address globals will
be faster than relative addressing; in many other machines there will be
no difference.  It depends on the implementation of the instruction set.

In an implementation which is not heavily tuned for run time performance
there is no advantage to using static area parameter handling because the
references are of the form

contents(fixed_offset + area address)

-- 

In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
	Richard Harter, SMDS  Inc.

leo@philmds.UUCP (Leo de Wit) (07/04/88)

In article <30305@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes:
>In article <546@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
>
>>So for static and 'static parameter list' variables. Even if you load
>>a register with the base of the list, you address the variables in it
>>relative to this base. That is as much computation as addressing relative
>>a frame pointer. On a paging system it may even take more, as the stack
>>pages are more likely to be in core than data pages - although a stack
>>pointer may behave weird, it will generally move in a relative small area.
>
>	I'm not sure I'm following this argument (or that it should be
>followed) but when has that ever stopped anyone.  Arguments about efficiency

The reason for me assuming a base register + offset addressing mode instead
of absolute addressing can be found below. Perhaps I should have been more
explicit.

>of different schemes are affected by how the hardware works.  In general,
>however, a static area calling sequence scheme will be more efficient than
>a stack scheme because the dirty work is done at link time rather than at
>execution time.  Attend:

 [stuff about address referencing inside function]

>Now, in a stack implementation, each reference to 'a' is of the form
>
>contents(fixed_offset + stack pointer)

 [talk about static references which eventually uses references like:]

>contents(fixed address)
>
>It doesn't necesarily work this way -- it is all a matter of how the system
>is set up.  But, given the supporting cast, static area calling sequences
>can be treated as globals.  In many machines absolute address globals will
>be faster than relative addressing; in many other machines there will be
>no difference.  It depends on the implementation of the instruction set.

This is simply NOT TRUE (or FALSE 8-), or, to be on the safe side,
there are a lot of cases in which the opposite holds. I don't know
which machines/architectures you are referring to, but I know of at
least one (quite popular) in which relative addressing is faster than
absolute addressing: the MC68000 and successors.

The reason is also quite simple: an absolute address (on the Motorola
32 bits) takes more bits to encode than a register relative address (on
the Motorola 16 bits; the addressing mode is called register indirect
with offset).  It takes more cycles to get the extra two bytes from the
bus than to perform the (short) implicit addition to a register.

That is the reason I suggested loading an address register also for the
static data, just because it makes the following stores/loads faster
(except if there are very few references, e.g. 1). Again, on the Motorola,
but I don't see why the same arguments shouldn't apply to other cpu's.

Here are some typical instruction sizes for the Motorola (assume a move
from a data register into memory):
register indirect: 2 bytes
register indirect with offset: 4 bytes
absolute: 6 bytes
If you move memory to memory, the situation gets even worse (assume two
address registers being used):
register indirect: 2 bytes
register indirect with offset: 6 bytes
absolute: 10 bytes

So instructions using the top of the stack (pushing & popping using 
register indirect, evt. combined with predecrement/postincrement) 
are MUCH faster, and the references of local variables (stack pointer
relative or frame pointer relative with offset) is faster than absolute
addressing (on several architectures).

I hope my point is made clear now: there are (quite a few) popular
cpu's for which register relative addressing is cheaper, if not much
cheaper than absolute addressing. Undoubtedly there will be others for
this is not the case (perhaps you should mention some for clarity,
since you talk about 'many architectures'). And this being the case, it
makes a good point in favor of stack addressing instead of static
absolute addressing, even when speed is at stake.

      Leo.

smryan@garth.UUCP (Steven Ryan) (07/05/88)

>How does FORTRAN b.t.w. handle the situation that there is a variable
>arguments list (cf. printf()) ? Seems a bit difficult with 'static lists'.
>Probably does not....

It is important to realise that a variable length argument list is variable
length from the called routine's point of view, not the caller's--it has the
argument list right there in its greedy little hands.

I saw two methods: a 170 appends a zero word terminator to the argument list.
A 205 passes the argument list length in the length field of argument list
point.

smryan@garth.UUCP (Steven Ryan) (07/05/88)

>	I'm not sure I'm following this argument (or that it should be
>followed) but when has that ever stopped anyone.  Arguments about efficiency
>of different schemes are affected by how the hardware works.  In general,
>however, a static area calling sequence scheme will be more efficient than
>a stack scheme because the dirty work is done at link time rather than at
>execution time.  Attend:

Thankyou.

Actually, the real discussion is why does C have such a crippled argument
list? It is possible to pass a list of argument descriptors. The descriptor
list can be staticcally created and the overhead is just a register load
of a relocated address.

Why not? Because most of the C users out there are more interested in
speed than security. Is that efficient?

cik@l.cc.purdue.edu (Herman Rubin) (07/05/88)

In article <870@garth.UUCP>, smryan@garth.UUCP (Steven Ryan) writes:

		........

> It is important to realise that a variable length argument list is variable
> length from the called routine's point of view, not the caller's--it has the
> argument list right there in its greedy little hands.
> 
> I saw two methods: a 170 appends a zero word terminator to the argument list.
> A 205 passes the argument list length in the length field of argument list
> point.

The use of a zero terminator works because FORTRAN uses call by address,
and zero is not a legal address in FORTRAN.  On some machines, zero cannot
be a legal address for anything, so it would work for all calls by address
in all languages.  

-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (ARPA or UUCP) or hrubin@purccvm.bitnet

leo@philmds.UUCP (Leo de Wit) (07/06/88)

In article <872@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:
>Actually, the real discussion is why does C have such a crippled argument
>list? It is possible to pass a list of argument descriptors. The descriptor
>list can be staticcally created and the overhead is just a register load
>of a relocated address.

What's the big deal? You can do that already in C. Just pass a list of
pointers to structs, they are equivalent to your 'descriptors'. Both
the structs and the pointers can be either statically allocated (so no
arguments are pushed on the stack) or pushed onto the stack (the
pointers, or even the structs themselves).

About the overhead:  you forgot to mention assignment to the data
elements; for instance an actual parameter that is an expression -
often calculated first into a register - has to be stored first into
the static area before the function can be called; there are a lot of
architectures that store much faster using stack pointer indirection
than using an absolute address (or even address register with offset).
And the data register still has to be loaded (I'm entitled to call this
overhead if the Fortran crew calls adjusting a stack pointer or setting
up a stack frame overhead; the last two instructions being even faster
than loading registers).

C has such a crippled argument list? I find it perfectly ok if you
don't like C - that's all on your account - but if you shout 'C has bad
this - C has bad that' you should argue that; things you take for
granted could well be less self-evident for C programmers. As far as I
can C (8-) - but you're of course free to correct me - C has at least
as many ways of passing parameters as Fortran.

      Leo.

ldm@texhrc.UUCP (Lyle Meier) (07/06/88)

In article <546@philmds.UUCP>, leo@philmds.UUCP (Leo de Wit) writes:
.
.
.

> How does FORTRAN b.t.w. handle the situation that there is a variable
> arguments list (cf. printf()) ? Seems a bit difficult with 'static lists'.
> Probably does not....
> 
According to the fortran 77 standard variable arguements are not allowed
between fortran programs, and the issue is not specified with respect to
other languages (They don't exist as far as the standard is concerned).
We ran into this issue in trying to build a binding of posix to fortran,
where we had to either break the number of characters in a variable name
(6) or the variable arguement list problem. We chose to break the name 
length issue. 
I believe the standard says the arguements must agree in number and type
between the caller and the callee. 

smryan@garth.UUCP (Steven Ryan) (07/08/88)

This was all started when somebody referred to braindead fortran programmers
who refuse to use a better structured language (better, not perfect). My point
has always been fortran is used for a purpose and anybody criticising fortran
should be propose a specific replacement that does what fortran does good
better. C, as it currently stands, does not.

Once people start claiming the difference is insignificant, that the gain in
clarity more than offsets the loss of cycles, then the same argument can
be used against C. Other languages are even better structured and more
secure than C. So what a small loss of machine cycles?

>>Actually, the real discussion is why does C have such a crippled argument
>>list? It is possible to pass a list of argument descriptors. The descriptor
>>list can be staticcally created and the overhead is just a register load
>>of a relocated address.
>
>What's the big deal? You can do that already in C.

The big deal is that anything that can be done in C can be done in
fortran--it's just a question of how understandable is the resulting
muckety mess.

nevin1@ihlpf.ATT.COM (00704a-Liber) (07/08/88)

In article <872@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:

>Actually, the real discussion is why does C have such a crippled argument
>list? It is possible to pass a list of argument descriptors. The descriptor
>list can be staticcally created and the overhead is just a register load
>of a relocated address.

This sounds to me that you want call-by-reference instead of call-by-value.
Personally, I prefer to have call-by-value and to explicitly say when I am
using a variable as a reference (my only exception to this preference is
when I am using a const reference).

>Why not? Because most of the C users out there are more interested in
>speed than security. Is that efficient?

Security in FORTRAN (with respect to calling conventions)??  Look at the
following piece of pseudoFORTRAN (I haven't used FORTRAN in about four
years and the exact syntax escapes me.  I'm sorry if I got this slightly
wrong, but here are the results when I did this same type of program four
years ago):

	subroutine foo(j)
	j = 5
	end
	...
	call foo(1)

This passes through the compiler with no problem.  If you look at the
run-time error, it's usually a memory violation and not a
compiler-generated error.  Some security.
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				You are in a little twisting maze of
 /  / _ , __o  ____		 email paths, all different.
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah

wes@obie.UUCP (Barnacle Wes) (07/08/88)

In article <30305@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes:
% ..........................  In many machines absolute address globals will
% be faster than relative addressing; in many other machines there will be
% no difference.  It depends on the implementation of the instruction set.

In article <550@philmds.UUCP>, leo@philmds.UUCP (Leo de Wit) writes:
> This is simply NOT TRUE (or FALSE 8-), or, to be on the safe side,
> there are a lot of cases in which the opposite holds. I don't know
> which machines/architectures you are referring to, but I know of at
> least one (quite popular) in which relative addressing is faster than
> absolute addressing: the MC68000 and successors.
> 
> The reason is also quite simple: an absolute address (on the Motorola
> 32 bits) takes more bits to encode than a register relative address (on
> the Motorola 16 bits; the addressing mode is called register indirect
> with offset).  It takes more cycles to get the extra two bytes from the
> bus than to perform the (short) implicit addition to a register.

Ah, yes, but on the 8086 in the large memory model, on entry into a
function, the DS segment register usually points to the default data
segment for the function, which is the stack.  If you want to access a
global location, you either have to: a) save DS, load the global segment
address into DS, access the value, then restore DS, or b) load the
global segment address into ES (the extra segment), then use ES:offset
addressing to get at the global data item.

Anyhow, in 8086 large model programming, typically local stack-based
variables are faster than global variables, because you don't have to do
any segment setup.  The Seive of Erastothenes bears this out - on the
68000 (Atari ST, MWC compiler), the Seive runs faster with a global array,
on the 8086 (MS QuickC), the Seive runs faster with a local array.
-- 
                     {hpda, uwmcsd1}!sp7040!obie!wes
           "Happiness lies in being priviledged to work hard for
           long hours in doing whatever you think is worth doing."
                         -- Robert A. Heinlein --

wes@obie.UUCP (Barnacle Wes) (07/08/88)

In article <872@garth.UUCP>, smryan@garth.UUCP (Steven Ryan) writes:
> Actually, the real discussion is why does C have such a crippled argument
> list? It is possible to pass a list of argument descriptors. The descriptor
> list can be staticcally created and the overhead is just a register load
> of a relocated address.
>
> Why not? Because most of the C users out there are more interested in
> speed than security. Is that efficient?

You can, easily.  Like this:

typedef enum {EOL, Char, Int, Char_ptr, Int_ptr } points_to_what;

typedef struct {
	points_to_what what;
	void *pointer;
} arg_item;

You create an array of `arg_item's, with the `what' field of the last
item being `EOL'.  This is, of course, much slower, but more secure.
The answer to your question `Why not?' is actually `Because it is not
necessary in the general case.'

Nobody is holding a pistol to your head forcing you to use C here - if
you don't like, go away and don't ruin our discussions!
-- 
                     {hpda, uwmcsd1}!sp7040!obie!wes
           "Happiness lies in being priviledged to work hard for
           long hours in doing whatever you think is worth doing."
                         -- Robert A. Heinlein --

raeburn@athena.mit.edu (Ken Raeburn) (07/08/88)

In article <553@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
>In article <872@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:
>>Actually, the real discussion is why does C have such a crippled argument
>>list? It is possible to pass a list of argument descriptors. The descriptor
>>list can be staticcally created and the overhead is just a register load
>>of a relocated address.
>
>What's the big deal? You can do that already in C. Just pass a list of
>pointers to structs, they are equivalent to your 'descriptors'. Both

Some differences here: If the compiler automatically does it, the
programmer doesn't have to do the work, the source code doesn't look
ugly, and the programmer isn't given the chance to screw up.

The Multics PL/I compiler (well, probably all of the Multics
compilers) did this sort of thing; there were calls available to get a
handle on the argument descriptor vector, and (I think) include files
around describing the structure and enumerating some of the possible
types.  I've never had to use this feature (except maybe indirectly via
debuggers), but the "overhead" involved was nothing that ever
concerned me; some extra space in the text section, and an instruction
or two at runtime.  (When a subroutine call is involved, the overhead
of a register-load is probably not significant, for large procedures.
If the procedure is small enough that you'd worry about it, you
probably want to inline your procedure anyways.)

There are times when I've wished for something like this to be
available under C; even if the language doesn't use it, you could
detect (probably in stack traces from core files) some cases when the
wrong arguments are being passed.  (Yes, I know, prototypes should
help with that too.  But BSD's pcc doesn't do prototypes.  On the
other hand, I use GNU CC -- which has a reasonable approximation of
dpANS-C -- as my default compiler anyways, so I'm trying to get in the
habit.)

How about a family of *printf routines that can detect type
mismatches?  The compiler would be hard-pressed to do this if you can
specify the format string at runtime....  Or, for your use in
debugging incredibly hairy code with monster data structures, a
pretty-printer routine which figures out what type the argument is and
displays it appropriately?

>About the overhead:  you forgot to mention assignment to the data
>elements; for instance an actual parameter that is an expression -

What has this to do with the static argument descriptor list?  The
types will be known at compile-time; they can be stored in a static
array (in the text section of the program, if feasible); only one
(constant) address needs to be loaded someplace special at runtime.

>C has such a crippled argument list? I find it perfectly ok if you
>don't like C - that's all on your account - but if you shout 'C has bad
>this - C has bad that' you should argue that; things you take for
>granted could well be less self-evident for C programmers.

Well, the uses I've mentioned above may or may not seem like useful
features.  There are a couple of other Multicians out there who may be
able to describe some uses of which I may be unaware.  (I would have
liked to have had a few more years with Multics before ours went away.
It was, from my understanding, sort of a predecessor to UNIX, or at
least in development when UNIX work started, and I find a lot of
things done right in Multics that some of the UNIX systems I've heard
of are just getting around to thinking about maybe sorta trying to do
someday soon....  Of course, it does go both ways.)

>      Leo.

~~ Ken Raeburn / raeburn@athena.mit.edu
   systems programmer
   MIT Project Athena

mat@emcard.UUCP (Mat Waites) (07/08/88)

In article <5234@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704a-Liber,N.J.) writes:
]
]Security in FORTRAN (with respect to calling conventions)??  Look at the
]following piece of pseudoFORTRAN:
]
]	subroutine foo(j)
]	j = 5
]	end
]	...
]	call foo(1)
]
]This passes through the compiler with no problem.  If you look at the
]run-time error, it's usually a memory violation and not a
]compiler-generated error.  Some security.
]-- 
] _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194

I have worked on several systems where the example code would run with no
problems.

No problems except that the constant "1" would have the value of 5 for
the rest of the program. This kind of problem can make for interesting
debugging sessions, especially for neo-fortranners.


Mat

-- 
 W Mat Waites            |                         |
 Emory Cardiac Data Bank | UUCP: gatech!emcard!mat |
 Atlanta, GA 30322       | PHONE: (404) 727-7197   |

wes@obie.UUCP (Barnacle Wes) (07/10/88)

In article <5234@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704a-Liber) writes:
> 	subroutine foo(j)
> 	j = 5
> 	end
> 	...
> 	call foo(1)
> 
> This passes through the compiler with no problem.  If you look at the
> run-time error, it's usually a memory violation and not a
> compiler-generated error.  Some security.

On the IBM 360 Fortran IV compiler, this would have the nasty effect of
making all future references to 1 come out 5.  The 360 instruction set
did not have any operations with immediate operands, so the Fortran
compiler would create a data area with "Define Constant" declarations
for each and every constant in the program.  If you choose to put
another value in your constants, that was your problem, not the
compilers, or the computers.  Like the old adage:

  "Constants aren't and variables won't."
-- 
                     {hpda, uwmcsd1}!sp7040!obie!wes
           "Happiness lies in being priviledged to work hard for
           long hours in doing whatever you think is worth doing."
                         -- Robert A. Heinlein --

rrr@naucse.UUCP (Bob Rose ) (07/11/88)

In article <5234@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704a-Liber) writes:
 > Security in FORTRAN (with respect to calling conventions)??  Look at the
 > 
 > 	subroutine foo(j)
 > 	j = 5
 > 	end
 > 	...
 > 	call foo(1)
 > 
 > This passes through the compiler with no problem.  If you look at the
 > run-time error, it's usually a memory violation and not a
 > compiler-generated error.  Some security.


Oh boy! You must be using some sort of new compiler. The old one's (not
all of course) would after running this code change _all_ integer constants
of value 1 to value 5. Try debugging the code after that occurs.
                                   -bob

rrr@naucse.UUCP (Bob Rose ) (07/11/88)

In article <892@garth.UUCP>, smryan@garth.UUCP (Steven Ryan) writes:
> The big deal is that anything that can be done in C can be done in
> fortran--it's just a question of how understandable is the resulting
> muckety mess.

Lets see malloc or alloca[1] in fortran without some low level routines
in some other language. Also recursion, yes you can make your own stack
but how big do you make this stack?
                            -bob

[1] alloca normally need to be written in assembly on most machines and
some need it built into the compiler (inline or whatever).

walter@garth.UUCP (Walter Bays) (07/13/88)

In article <774@naucse.UUCP> rrr@naucse.UUCP (Bob Rose ) writes:
>Lets see malloc or alloca[1] in fortran without some low level routines
>in some other language. Also recursion, yes you can make your own stack
>but how big do you make this stack?

Most large applications I've seen on UNIX have been 99% Fortran + 1% C,
or 100% C.  Most large applications I've seen on other OS's have been
99% Fortran + 1% Assembly Language.  I don't like to read or write
Fortran, but the fact that it's inappropriate for certain low level
routines doesn't change the fact that it's appropriate for some
applications.

Perhaps Fortran would be a less viable alternative were it not for
assistance from C.  I've also seen time-critical applications that were
80% Fortran and 20% Assembler.  (Fortran didn't give enough low-level
control in the time-critical sections.)  These applications were
nightmares that locked the users into obsolete hardware and operating
systems, because the cost to convert was too high.  Though the
low-level hardware dependencies will always be difficult, 80% Fortran +
20% C is much more portable, making Fortran a safer choice for the
application.
-- 
------------------------------------------------------------------------------
My opinions are my own.  Objects in mirror are closer than they appear.
E-Mail route: ...!pyramid!garth!walter		(415) 852-2384
USPS: Intergraph APD, 2400 Geng Road, Palo Alto, California 94303
------------------------------------------------------------------------------

smryan@garth.UUCP (Steven Ryan) (07/13/88)

>Lets see malloc or alloca[1] in fortran without some low level routines
>in some other language. Also recursion, yes you can make your own stack
>but how big do you make this stack?

I'll let some fortran freak rise and show how to abuse blank common. In
addition, some low level routines? Does this mean C is not sufficient for
itself? And how big do you make a stack for stack based languages? The only
difference is whether you securely implement it out of sight and out of
mind, or make it big as life and twice as natural?

g-rh@cca.CCA.COM (Richard Harter) (07/13/88)

In article <941@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:
>>Lets see malloc or alloca[1] in fortran without some low level routines
>>in some other language. Also recursion, yes you can make your own stack
>>but how big do you make this stack?

>I'll let some fortran freak rise and show how to abuse blank common. In
>addition, some low level routines? Does this mean C is not sufficient for
>itself? And how big do you make a stack for stack based languages? The only
>difference is whether you securely implement it out of sight and out of
>mind, or make it big as life and twice as natural?

I worked on a project circa 1972 where we did this --  dynamic storage
allocation using blank common, emulated structures and pointers, and so
on.  I've posted the relevant techniques once -- damned if I'll do it
again.  If you want to know how to do it, figure it out for yourself.

Real programmers don't whimper about the language they are stuck with;
they just do it with whatever they have to work it.  They don't make
wimpy comments about "you can't do x in language y".  You could write
the unix kernel in fortran if you wanted to; you could write it as a
teco macro if you wanted.  If it turns you on and you've got the bucks,
I'll do it for you.  [My rates for this kind of work start at $1000 an
hour -- this includes a mental abuse surcharge.  :-)]

Note: These crochety comments are addressed to the chap that Steve quoted.
Steve sounds like a sensible sort of fellow to me.
-- 

In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
	Richard Harter, SMDS  Inc.

bill@proxftl.UUCP (T. William Wells) (07/14/88)

In article <773@naucse.UUCP>, rrr@naucse.UUCP (Bob Rose ) writes:
) In article <5234@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704a-Liber) writes:
)  > Security in FORTRAN (with respect to calling conventions)??  Look at the
)  >
)  >    subroutine foo(j)
)  >    j = 5
)  >    end
)  >    ...
)  >    call foo(1)
)  >
)  > This passes through the compiler with no problem.  If you look at the
)  > run-time error, it's usually a memory violation and not a
)  > compiler-generated error.  Some security.
)
)
) Oh boy! You must be using some sort of new compiler. The old one's (not
) all of course) would after running this code change _all_ integer constants
) of value 1 to value 5. Try debugging the code after that occurs.
)                                    -bob

Back in the days of punch cards, I once substituted a `1' for an
`I' in a subroutine call. This was not that hard to do given
that they were just a shift away.  And the printer on the
keypunch wasn't that good; one could examine the print all day
and not tell the difference. Of course the program acted really
strange when the function modified that argument.

Anyway, I spent THREE DAYS finding this. I finally found it by
assuming that it was a compiler bug and doing the usual
cut-out-code stuff. Of course, it wasn't a compiler bug, just a
typo. Arg...

Eighteen years later, I still remember.  Anyway, it's things
like that that have given, at least to me, call-by-reference as
the default a bad odor.

SMITHJ@ohstpy.mps.ohio-state.edu (08/04/89)

This may have been discussed here millions of times before, but here it goes.

What are the reasons for using FORTRAN over C?

I have heard claims that the code is easier to optimize and that current
benchmarks show that this is the case on all mainframes.  My experience is
that this is pure bu****it.  Have done my own testing, I find that C runs
faster on PC's.

Is it likely that C runs slower--on say the VAX--because it is only in
version 2.4 whereas the FORTRAN compiler is at version 90+ (i.e. fewer
man hours have been put into developing mainframe C compilers)?

No remarks about the ease of use of complex numbers in FORTRAN are acceptable.
-- 
/* Jeffery G. Smith, BS-RHIT (AKA Doc. Insomnia, WMHD-FM)       *
 *    The Ohio State University, Graduate Physics Program       *
 *        3193 Smith Lab, Columbus, OH 43210  (614) 292-5321    *
 *    smithj@ohstpy.mps.ohio-state.edu                          */

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/04/89)

In article <3288@ohstpy.mps.ohio-state.edu> SMITHJ@ohstpy.mps.ohio-state.edu writes:
>What are the reasons for using FORTRAN over C?

The main legitimate one is that there are large libraries of numerical
software on tap for Fortran users, less so for C users.

Around here the main reason is, or was, that scientists and engineers
are doing their own programming (for whatever reason) and having spent
considerable effort learning Fortran, which seems "good enough" to them,
they have no desire to learn C.  They may have a desire for assistance
from genuine computing professionals, but they're not being staffed
for that.

>I have heard claims that the code is easier to optimize ...
>...  My experience is that this is pure bu****it.

C has some features that make optimization more difficult and less
complete, the primary one being the potential for pointer aliasing.
Although Fortran can also have aliasing, the problem is more sever
for C.  In spite of the difficulties, there are some extremely good
optimizing C compilers in existence.

>Is it likely that C runs slower--on say the VAX--because it is only in
>version 2.4 whereas the FORTRAN compiler is at version 90+ (i.e. fewer
>man hours have been put into developing mainframe C compilers)?

Older UNIX distributions included a Fortran implementation that
(justifiably) received far less attention than the C environment;
certainly there, relative compiler quality was a factor -- although
in the opposite direction!  The demand for hyper-efficient C code
generation is relatively recent, whereas Fortran users have always
been sensitive to code "efficiency".  Many computer vendors these
days use essentially the same code generator for all their Algol-
like language compilers.

The odds are pretty good that somebody asking about relative code
efficiency is worrying about the wrong issues in choosing a
programming language.

kemnitz@mitisft.Convergent.COM (Gregory Kemnitz) (08/04/89)

In article <3288@ohstpy.mps.ohio-state.edu> SMITHJ@ohstpy.mps.ohio-state.edu writes:
>This may have been discussed here millions of times before, but here it goes.

It has :-)

>
>What are the reasons for using FORTRAN over C?
>

Compatibility with or upgrades to existing software, which is likely to be
huge, unwieldy, and politically entrenched (ie it is difficult/impossible
to convince management that it should be re-written).  Also, FORTRAN compilers
on Crays are better (generate faster, more vectorized code) than the C
compilers.

>I have heard claims that the code is easier to optimize and that current
>benchmarks show that this is the case on all mainframes.  My experience is
>that this is pure bu****it.

I suspect that on (scalar) mainframes the "ease of optimization" is, as you
mention below, due more to the relative maturity of FORTRAN compilers on these
platforms than to any inherent advantages of the language.  Many mainframe
vendors originally just ported PCC to their machines and shipped it as "their" C
compiler.  This situation, however, is improving with time (and UNIX).

> Having done my own testing, I find that C runs
>faster on PC's.

This is true.  There is a much larger market for good C compilers on
PC's than there is for FORTRAN compilers, since many big FORTRAN programs
solve problems that would choke PC's in any language no matter how well
compiled, and small FORTRAN programs are often easier to rewrite in C
than to port to PC's in FORTRAN.

>
>Is it likely that C runs slower--on say the VAX--because it is only in
>version 2.4 whereas the FORTRAN compiler is at version 90+ (i.e. fewer
>man hours have been put into developing mainframe C compilers)?
>

(See above)

About the VAX, however:

The VAX (running VMS) was for many years the machine of choice in industry for
developing software in FORTRAN.  The software development environment in VMS
is built around FORTRAN, much as UNIX is built around C.  The programming
style used for VMS shell scripts is quite familiar to the FORTRAN programmer.

The VAX extensions to FORTRAN made it an (almost) acceptable language - while
making VAX FORTRAN quite unportable :-)  The VAX is popular enough that many
newer FORTRAN compilers understand most VAX extensions, however.

>No remarks about the ease of use of complex numbers in FORTRAN are acceptable.

I can hear the flamethrowers firing up now...

Disclaimer:  :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-)

>-- 
>/* Jeffery G. Smith, BS-RHIT (AKA Doc. Insomnia, WMHD-FM)       *
> *    The Ohio State University, Graduate Physics Program       *
> *        3193 Smith Lab, Columbus, OH 43210  (614) 292-5321    *
> *    smithj@ohstpy.mps.ohio-state.edu                          */

----------------------------------+--------------------------------------
Greg Kemnitz                      | Software without hardware is an idea.
kemnitz@Convergent.COM            | Hardware without software is a space heater.
soon:				  |
kemnitz@postgres.berkeley.edu     | --Unknown author

bryan@stiatl.UUCP (Bryan Donaldson) (08/04/89)

In article <3288@ohstpy.mps.ohio-state.edu> SMITHJ@ohstpy.mps.ohio-state.edu writes:
>What are the reasons for using FORTRAN over C?
>/* Jeffery G. Smith, BS-RHIT (AKA Doc. Insomnia, WMHD-FM)       *

One of the best reasons I can think of is where you have 200K+ lines of Fortran
code that you don't want to convert.  Admittedly, on PC's today, there are 
compiler systems where you can link C and Fortran together, But that only
allows you to put all new code in C. (Of course, it brings up the interlanguage)
problem.)

Bryan G. Donaldson


-- 
Bryan Donaldson                                             gatech!stiatl!bryan
Sales Technologies, Inc
3399 Peachtree Rd, NE
Atlanta, GA  (404) 841-4000

flint@gistdev.UUCP (Flint Pellett) (08/05/89)

One thing I've heard FORTRAN touted for was "portability": the claim being
that it is more portable than any other language.  I don't believe that:
C is far more portable.  I base that conclusion on this fact: C has defined
standards for capailities FORTRAN doesn't have standards for.  For
example, C code to get the command line arguments works everywhere, but
in FORTRAN, if you can even do it, you can guarantee that the way you
do it doesn't match from system to system.  The same goes for library
calls, on some very basic things: one system will have "ior(), the next
will name it "or()".  Then comes hex constants: where you have to convert
the z'abcd' of one compiler into #abcd for another, etc.

mcdonald@uxe.cso.uiuc.edu (08/06/89)

>The odds are pretty good that somebody asking about relative code
>efficiency is worrying about the wrong issues in choosing a
>programming language.

I don't understand this statement! Somebody serious about relative
code efficiency (and mentioning Fortran) probably has a big program.
They may be worried that it would cost $20000 of cpu time in
one language instead of $40000 in another. This isn't important?
OR they might be worried that one would take 300 microseconds to
process a piece of incoming data, and another language might take
600 microseconds, and the data is expected to arrive at 400 microsecond
intervals.

If efficiency matters at all then it usually is the MOST important issue.
Sometimes it is even more important than getting the "right" answer (!),
as in using a some math function (say sin(x)) that is only good to three
significant digits, just to be faster, rather than in using a slower
but more accurate routine..

Doug McDonald

tneff@bfmny0.UUCP (Tom Neff) (08/07/89)

In article <225800204@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes:
>>The odds are pretty good that somebody asking about relative code
>>efficiency is worrying about the wrong issues in choosing a
>>programming language.
>
>I don't understand this statement! Somebody serious about relative
>code efficiency (and mentioning Fortran) probably has a big program.
>They may be worried that it would cost $20000 of cpu time in
>one language instead of $40000 in another. This isn't important?
>OR they might be worried that one would take 300 microseconds to
>process a piece of incoming data, and another language might take
>600 microseconds, and the data is expected to arrive at 400 microsecond
>intervals.

Yes - they MIGHT.

More likely, in my experience, they just like the *idea* of efficient
code, whether or not they can demonstrate just what DEGREE of efficiency
their application requires.

All you have to do is stand around the lunchroom when a bunch of
applications hackers are standing around gossiping about processors and
compilers.  Oh, THAT's got more mips than THIS one!  Oooh, I don't like
THAT compiler, it generates less efficient code!  Say, duhh, which is
better, the 88000 or 486?  Huhhh?

<Burp> The fact is that every extra hour the applications wonk spends
trying to get the #*$&@# compiler or linker or OS loader to work,
or on the phone to some consultant, is worth billions of instructions
on any processor of his choice.  Software that works right, and early,
is more important that a shaved MIP.  However this does not make for
sufficiently macho lunchroom conversation!

-- 
"We walked on the moon --	((	Tom Neff
	you be polite"		 )) 	tneff@bfmny0.UU.NET

flanner@prls.UUCP (Philip D. Flanner III) (08/08/89)

The usual efficiency vs timeliness, correctness etc battle is starting up
again; here are a couple non-anecdotal contributions:

A company paid me ~$2500 to write ~120 lines of code to perform a certain
function.  They already had an efficient, working version but it wasn't
fast enough, and they had to hire a consultant (me!) to squeeze the last
few microseconds out of it.  Why? because, although it was fast, it wasn't
fast enough to handle the data coming from the wingtip flight recorder.
Even worse, I coded it in assembler [gasp]!

I spent many days [at the behest of my employer] on a working program
(~8000 lines) trying to make it more efficient (only where it counted, 
in three routines totalling about 1/10 the whole program), because
the piece of equipment it controlled needed to have a <100 millisecond
control loop, otherwise it might just fly apart and hurt people.

Moral:  There ARE often reasons why efficiency is of paramount importance;
	just because you've never had to work on such a project doesn't
	mean there aren't a lot of them out there.  I also agree that a
	fanatic devotion to efficiency in cases where it is not important
	is just that : fanatic.

-- Phil Flanner   ..!philabs!prls!flanner  -or-  ..!decwrl!pyramid!prls!flanner

tneff@bfmny0.UUCP (Tom Neff) (08/08/89)

There are always projects floating around that DO require squeezing the
last cycle out of a module, and I've worked my share of them; but there
is a preponderance of projects where this kind of cycle squeezing is a
waste of the company's money.  The trick is knowing how to tell the
difference, and I find that many programmers don't.  

For every exceptional story where someone had to shave a DECX
instruction to keep the Exxon Valdez autopilot in synch, there are 10
real life stories within a block of me where people are rewriting
once-a-day startup modules in assembler because they think it's cool to
"use tighter code."  Or a hacker consultant sitting at his desk pounding
out incomprehensible spaghetti code and greeting puzzled inquiries with
that withering look and the cry, "Listen sucker THIS has to run FAST!"
... followed by the inevitable sequel scene three years later when I'M
still there and the COMPANY'S still there and this MODULE'S still there
-- dead in the water -- but the consultant is now a rafting instructor
in Utah somewhere and Joe Tyro is tasked with fixing the code.

Knowing WHEN to optimize is as important as knowing HOW.
-- 
"We walked on the moon --	((	Tom Neff
	you be polite"		 )) 	tneff@bfmny0.UU.NET

jlg@lanl.gov (Jim Giles) (08/09/89)

From article <14523@bfmny0.UUCP>, by tneff@bfmny0.UUCP (Tom Neff):
> [...]                            Software that works right, and early,
> is more important that a shaved MIP.  [...]

In that case, Fortran is certainly a better choice than C for most
numerical computations.  Fortunately, it also helps if you're after
shaving a few MIPs as well.

The best test for a programming language is that simple concepts should
be simple to represent.  For numerical computations, Fortran does this
better than C.  Consider, for example, a routine to do matrix multiply
on arbitrary sized and shaped matrices - both C an Fortran require the
programmer to express the iteration explicitly, but only C requires the
index calculations to be done explicitly.  C++ does better, but only
if the programmer has implemented a class for matrices and the definitions
of the operations.  Still, it's a step in the right direction - when will
we see a Fortran++ ?

henry@utzoo.uucp (Henry Spencer) (08/09/89)

In article <14014@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>... Still, it's a step in the right direction - when will
>we see a Fortran++ ?

By the time the Fortran 8x committee gets done, sometime in the 21st century,
it will probably have produced Fortran++++++++++ or so.  By which time, of
course, nobody will care....

:-) :-) :-) :-) :-) :-) :-)
-- 
1961-1969: 8 years of Apollo.  |     Henry Spencer at U of Toronto Zoology
1969-1989: 20 years of nothing.| uunet!attcan!utzoo!henry henry@zoo.toronto.edu

tps@chem.ucsd.edu (Tom Stockfisch) (08/11/89)

In article <14014@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>From article <14523@bfmny0.UUCP>, by tneff@bfmny0.UUCP (Tom Neff):
>> [...]                            Software that works right, and early,
>> is more important that a shaved MIP.  [...]
> In that case, Fortran is certainly a better choice than C for most
> numerical computations.

I have to disagree.

> Fortunately, it also helps if you're after shaving a few MIPs as well.

That's not true on most of the machines I use.  In fact, for scientific
programming that uses a lot of integer operations, C is almost always
faster as well as more convenient because of built-in, portable bit
operators and fewer restrictions on what constitutes an integer.

> Consider, for example, a routine to do matrix multiply
> on arbitrary sized and shaped matrices - both C an Fortran require the
> programmer to express the iteration explicitly, but only C requires the
> index calculations to be done explicitly.

Not really.  You can either use a macro, such as

	vecFn( a, nrow, ncol )
		double	*a;
	#		define A( i, j )	a[ (i)*ncol + (j) ]
	{
		int	i, j;
		...
		A(i,j)
		...
	}

Or, better, use a storage allocator that returns a pointer to the
first element of an array of pointers, each of which point to a row
of your matrix.  Then you have

	vecFn( a, nrow, ncol )
		double	**a;	/* nrow X ncol pseudo-matrix */
	{
		int	i, j;
		...
		a[i][j];
	}


Numerical algorithms have both a speed complexity and memory complexity,
and portable storage allocation is a big win for numerical C programs.
It's a major headache to edit and recompile fortran programs every time
you want to change the size of your problem.  And if you don't change
it back downwards you wind up with a 1000X1000 matrix swapping to disk
when your calculating the 10X10 case.

Sparse matrices are also easier in C.

> C++ does better, but only if the programmer has implemented a class...

Actually, the major advantage of C++ for numerical programming is complex
numbers.  This is the only place I use fortran, as C++ is not yet universally
available.

>when will we see a Fortran++ ?

It would have to be called "      FORTRAN = FORTRAN + 1.0E+00".
I think its a bad idea to make a new language upwardly compatable
from the Original Language.  When will we see Fortran die and fade away?
-- 

|| Tom Stockfisch, UCSD Chemistry	tps@chem.ucsd.edu

idall@augean.OZ (Ian Dall) (08/11/89)

I think I'm going to regret this posting but...

In article <14014@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>
>be simple to represent.  For numerical computations, Fortran does this
>better than C.  Consider, for example, a routine to do matrix multiply
>on arbitrary sized and shaped matrices - both C an Fortran require the
>programmer to express the iteration explicitly, but only C requires the
>index calculations to be done explicitly.

It's been a long while since I programmed in FORTRAN but I did do quite
a lot of it once and I know of know way of handling arbitrary shaped
multidimensioned arrays in FORTRAN. You are not thinking of a vendor
specific enhancement are you? Or maybe one of these new fangled versions
of FORTRAN do indeed have such support.

LOTS of FORTRAN subroutines use indicies of the form I*XDIM + J
and if that isn't explicit index calculation I don't know what is!
-- 
 Ian Dall           life (n). A sexually transmitted disease which afflicts
                              some people more severely than others.
idall@augean.oz

jlg@lanl.gov (Jim Giles) (08/15/89)

From article <517@chem.ucsd.EDU>, by tps@chem.ucsd.edu (Tom Stockfisch):
>>> is more important that a shaved MIP.  [...]
>> In that case, Fortran is certainly a better choice than C for most
>> numerical computations.
> 
> I have to disagree.

Fine.  Just don't try to force _your_ decision on anyone else.

>> Fortunately, it also helps if you're after shaving a few MIPs as well.
> 
> That's not true on most of the machines I use.  [...]

It is for most of the machines _I_ use - by a LOT!  In C, every pointer
(and, therefore most arrays) must be assumed to be aliased to every
other pointer.  Code must be generated under this assumption.  In Fortran,
all objects are locally declared (even non-local objects), so the compiler
_knows_ which are aliased to which.  Since aliasing can inhibit most
optimizations on pipelined, parellel, and vector machines, C is clearly
slower on such machines (unless unsafe optimizations are performed).
Aside from this difference, C and Fortran are equally difficult (or easy)
to optimize - and the same optimization techniques work for both.  The
only places I've ever seen C beat Fortran are _very_ simple machine
architectures (no pipelining, etc.) or on small machines where the
compiler omits most optimization techniques to make the compiler small
enough to fit on the machine.

>> Consider, for example, a routine to do matrix multiply
>> on arbitrary sized and shaped matrices - both C an Fortran require the
>> programmer to express the iteration explicitly, but only C requires the
>> index calculations to be done explicitly.
> 
> Not really.  You can either use a macro, [...]

Why should I have to declare a macro for something Fortran has built-in?
Doesn't sound like an advance to me.  Besides, I have used macros in
Fortran for years.  The advantage with Fortran is that I _start_ with
a more complete array syntax.

> Or, better, use a storage allocator that returns a pointer to the
> first element of an array of pointers, each of which point to a row
> of your matrix.  Then you have [...]

A multidimensional array is _NOT_ an array of pointers to pointers to ...!
Implementing it this way slows down all array accesses by the number
of indirections required.  Further, since each of the pointers in a
pointer array is assumed to be aliased to the others, optimization is
_really_ squashed.  A good compiler will move the indirections out of
middle loops (if you have a NOALIAS directive it will), but they still cost.
Fortran 8x will have allocatable arrays which will allow portable dynamic
arrays to be declared without _any_ multiple indirection overhead.  In the
meantime, it is cheaper to recompile with different sizes than to pay for
the overhead on a large numerical code.

> Sparse matrices are also easier in C.

I've heard this claim before, but I've never seen any advantage of either
language for this.  In either case, the programmer must code a lot of index
calculations - the only difference is whether the calculated index is
added to a pointer or used as a subscript - big deal.

> [...]
>>when will we see a Fortran++ ?
> 
> It would have to be called "      FORTRAN = FORTRAN + 1.0E+00".
> I think its a bad idea to make a new language upwardly compatable
> from the Original Language.  When will we see Fortran die and fade away?

I agree that backward compatibility is a double-edged issue.  C++ would
have been _MUCH_ better if they had eliminated pointer-array equivalence,
but then it wouldn't have been backward compatible.

As for when Fortran will die - well if languages die in order of design
quality (with lowest quality dying first) then Fortran will die after C
does.  Unfortunately, the success of a programming language seldom has
much correlation with the quality of the language.  So, I think Fortran
will die with the introduction in 8x of the world's worst pointer facility.

mouse@mcgill-vision.UUCP (der Mouse) (08/15/89)

In article <14523@bfmny0.UUCP>, tneff@bfmny0.UUCP (Tom Neff) writes:
> In article <225800204@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes:
>>> The odds are pretty good that somebody asking about relative code
>>> efficiency is worrying about the wrong issues in choosing a
>>> programming language.

>> Somebody serious about relative code efficiency (and mentioning
>> Fortran) probably has a big program.  [...] $20000 of cpu time in
>> one language instead of $40000 in another.  [...300 microseconds in
>> one language, 600 in another, with a 400 microsecond requirement...]

> Yes - they MIGHT.

> More likely, in my experience, they just like the *idea* of efficient
> code, whether or not they can demonstrate just what DEGREE of
> efficiency their application requires.

This is not entirely silly; it pays off big when said person has to
write something where efficiency *is* important for a change.

Of course, it can be (and too often is) carried to excess.

> <Burp> The fact is that every extra hour the applications wonk spends
> trying to get the #*$&@# compiler or linker or OS loader to work, or
> on the phone to some consultant, is worth billions of instructions on
> any processor of his choice.

Yeah, so what?  If I can shave 10% off of my compiles, that's a lot of
time.  Suppose it takes me a week to save that 10%: then after I spend
a total of nine weeks waiting for compiles, I've broken even: that
would have been ten weeks.  After that it's clear gain.

It would take *me* a long time to build up nine weeks of
waiting-for-compile time.  But if the compiler is in use by nine
people, that's *one* week of waiting time per person.  Sixty-three
people and it's a day of waiting time, which might be a week of working
time.

Now, if the compiler is sold to eight thousand customers...I'll let you
work out the arithmetic for yourself. :-)

> Software that works right, and early, is more important that a shaved
> MIP.

*Almost* always.  (I remember a wonderful sentence from somewhere or
other: "Presumably this means it is important to get the wrong answers
quickly."  I do not recall the context or source, but it certainly
sounds good.)

Being able to tell whether a given situation is such that speed is
worth spending effort on is part of what makes a good programmer.
The world needs more good programmers.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

clevea@bcsaic.UUCP (Cleve Ashcraft) (08/16/89)

In article <14017@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>
>From article <517@chem.ucsd.EDU>, by tps@chem.ucsd.edu (Tom Stockfisch):
>
>> Sparse matrices are also easier in C.
>
>I've heard this claim before, but I've never seen any advantage of either
>language for this.  In either case, the programmer must code a lot of index
>calculations - the only difference is whether the calculated index is
>added to a pointer or used as a subscript - big deal.
>

as someone who works with sparse matrices, i will agree with the
first statement, with the following qualification. just about
any numerical work on sparse matrices uses the following kernels,
quoted in C syntax.

daxpy :
for ( i = 0 ; i < size ; i++ )
   x[i] += alpha * y[i] ;

daxpyi :
for ( i = 0 ; i < size ; i++ )
   x[indices[i]] += alpha * y[i] ;

ddot :
for ( i = 0, sum = 0. ; i < size ; i++ )
   sum += x[i] * y[i] ;
return sum ;

ddoti :
for ( i = 0, sum = 0. ; i < size ; i++ )
   sum += x[i] * y[indices[i]] ;
return sum ;

in general, these kernels do not have their vector arguments
overlapped, and thus can be vectorized. some type of compiler
directive should be made available to generate good code on
vector machines. however, C has no advantage over Fortran for
these kernels.

where C does have an advantage is found in the ordering of
sparse matrices, the setting up of higher level graph structures,
and the dynamic storage allocation. sparse matrix algorithms
have gone a long way past the simple general sparse algorithm.
references on request.

i switched over to C about 18 months ago, and the productivity
benefits have made it worth it.

cleve ashcraft
clevea@atc.boeing.com

noren@dinl.uucp (Charles Noren) (06/07/90)

I've been getting additional e-mail about a C vs. FORTRAN
comparison list.  I may have betrayed a language bias which
I don't want to do, additionally I've been making unfair
comparisons of old FORTRAN compilers to modern C compilers.

The risk of comparing languages is the tendency to start
religious holy wars in support of one language over another.
This certainly was not the intent of the orignal asker nor do
I want to do that.  What I'm trying to do is stick my neck out
with raising a few ideas and solicit comment from the network
to help the orignal poster to make an intelligent decision of
whether or not move from FORTRAN to C.  I would say the answer
is not obvious to me (I welcome e-mail flames and will summarize
to my best the important points -- as you can probably tell, I'm
no compiler guru).  Also, take whatever I say with a grain of
salt.  I have a bias towards C and the comments may reflect this
(and, I should note, my bias does not have entirely rational
causes).

This discussion probably does not fit the charter of comp.lang.c
so I'm directing follow-ups to comp.lang.misc.

I was an old user of FORTRAN, FORTRAN IV in fact.  Modern FORTRANs
have evolved over time and thus some of the things I listed as C
advantages are also found in modern FORTRAN compilers.  These, I'm
told, include:

Modern FORTRAN enhancements:

 1.  Data Structures.  FORTRAN IV did not have them, modern
     FORTRAN compilers do.
 2.  Cleaner code structures.  Apparently the newer FORTRAN
     compilers have modern code structures.  As one person
     noted, his FORTRAN code is essentially free of statement
     labels and indented for readability.
 3.  Recursive subroutine calls.  Most, if not all, modern
     FORTRAN compilers can call subroutines recursively.
     This is many a feature of the underlying implementation
     of how arguments are passed to subroutines/functions.
     (Question to langauge definition guru's: Are recursive
     and reentrancy issues specified in the formal langauge
     specifications of C and FORTRAN?)
 4.  Free form code.  Modern FORTRAN compilers allow for free
     form entry of code, with similar restrictions that apply
     to C code with its pre-processor statements (e.g., #define).

And now a C advantage list.

C Advantages over FORTRAN:

 1.  Data Pointer Types.  FORTRAN apparently still does not
     have a pointer type.  Underlying argument passing
     mechanisms in FORTRAN subroutines probably use pointers,
     but the language definition does not have a data pointer
     type.  Data pointers conveniently allow referrences to
     physical memory (useful for microprocessor controllers,
     perhaps not useful for virtual memory machines) and the
     "more natural" creation and maintenance of some data
     structures such as linked lists.
 2.  Function Pointer Types.  One person commented that it is
     possible to pass a single function explicitly in FORTRAN,
     but a "table" of pointers to functions cannot be created
     created in FORTRAN.
 3.  Ability to have variable argument lists.  As some have
     pointed out, this feature in C is somewhat awkward
     (this is in the eye of the beholder) and thus not
     considered by some as a major advantage.
 4.  Macros.  In most C implementations, macros are expanded
     in seperate program from the actual C compiler, known as
     the C Pre-Processor (cpp).  One person suggested that
     FORTRAN code could be run through cpp an thus have macros.
     I have not tried this, but it is an interesting idea.
 5.  Dynamic memory allocation.  f77 does not have this, but
     apparently f9x will have dynamic memory allocation.

FORTRAN Advantages over C:

 1.  Lack of pointer types.  Pointers in C (and how their
     relation to and distiction from arrays) often are a 
     stumbling block to new C programmers (and sometimes 
     old C programmers).
 2.  FORTRAN environments probably have more mature math
     libraries.  Some C programmers pointed out that they
     link to some FORTRAN math libraries.
 3.  Fortran compilers have been around longer and are
     generally better at optimization than C compilers.
 4.  The Fortran language is designed so that compilers
     can make useful assumptions for code optimization,
     which cannot be made for C compilers.  Two examples:
      a.  Aliasing is not permitted in Fortran.
          For instance, if you declare two array arguments in
          a Fortran subroutine, those arguments cannot be the
          same array -- if they are read and write arguments.
          This permits the subroutine to be compiled
          with very fast vector instructions (on machines that
          support vectorization such as Crays).
          (One person mentioned that there are are good ways
          for compilers to get around the aliasing problem --
          so this is not such a disadvantage to C.  I must
          say that I plead ignorance here.)
          (Question:  It's been so long since I've used
          FORTRAN, but how does the EQUIVELANCE statement
          affect or not affect aliasing?)
      b.  The C for statement does not have a well defined
          "control variable" and thus cannot be automatically
          vectorized.
 5.  *Natural* array subscripts in C must start with zero, 
     which for some is counter intuative (of course the C 
     programmer might ask what is so intuative about starting 
     with 1 ;-)).  One person mentioned this can cause 
     optimization problems by defeating alias optimizations in 
     C, again I don't know if this is the case.  Modern FORTRAN
     compilers, I'm told, allow for subscripts to start at
     any value (including negative integer values).  Several
     people reminded my that C arrays do not have to be zero
     based.  With macros and pointers one could use any integer
     value in an array reference.  However, it would seem that
     FORTRAN, with its way specifying a starting index (if it
     truely is part of "standard" FORTRAN and not just a vendor
     language enhancement) has the advantage here.
 6.  C does not permit multidimensional array parameters of
     different sizes.  C is certainly powerful enough the
     work around this, but it does not have the built-in
     stuff that FORTRAN has (with its possible built-in
     optimization).
 7.  C does not have the COMPLEX data type.  Of course
     through data structures this kind of thing could be
     implemented in C.  However, it is built-in in FORTRAN,
     with libraries already built to support it, and
     probably built-in optimization.
 8.  C has somewhat confusing reserved word adjectives
     for storage classes, which also vary in meaning depending
     on the context.  A classic example is the C reserved
     word "static".  It has an aspect of meaning "unchanged"
     in that variables declared as such inside functions
     retain there last value from function exit and the
     next invocation of the function.  "static" also has the
     meaning of global only the to module file the "static"
     function or "static global" data resides (in other words
     its local to that file).
 9.  Dynamic memory.  Due to the use of pointers in C,
     dynamic memory is used often in C.  How and when to use
     dynamic memory (and which are the best dynamic memory
     functions) can cause debate with C programmers.  With the
     use of dynamic memory come subtle bugs (memory leaks) which
     can be hard to trace.


I have certainly missed some points and corrupted others.
Flames and comments are welcome.

Thanks to the following people whose comments I've
incorporated (but don't blame them for my errors):

 o  Andrew Mullhaupt (mailrus!uunet!Morgan.COM!amull)
 o  a person from Microsoft (whose name I could not locate in
    the mail header).
 o  John Sahr (thalatta.com!calvin!johns@cs.utexas.edu)
 o  another person I could not identify from the mail header.
 o  Roger Cole (cole@luke.lanl.gov).
 o  Dan Bernstein (brnstnd@stealth.acf.nyu.edu).


-- 
Chuck Noren
NET:     ncar!dinl!noren
US-MAIL: Martin Marietta I&CS, MS XL8058, P.O. Box 1260,
         Denver, CO 80201-1260
Phone:   (303) 971-7930