fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (08/30/88)
I am looking for opinions of experienced numerical/scientific/engineering programmers along the lines of why Fortran is a better language than C for numerical analysis. Actually, I'll take any opinions at all as a starting point. I'm particularly interested in hearing from people who have actually attempted significant (your definition) implementations in C and gone back to Fortran, and from people who are just simply unwilling to use C at all. Reply to me, and I'll sumarize if there is enough interest: fouts@lemming.nas.nasa.gov ..!ames!orville!fouts +-+-+-+ I don't know who I am, why should you? +-+-+-+ | fouts@lemming.nas.nasa.gov | | ...!ames!orville!fouts | | Never attribute to malice what can be | +-+-+-+ explained by incompetence. +-+-+-+
jlg@lanl.gov (Jim Giles) (09/01/88)
From article <893@amelia.nas.nasa.gov>, by fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts): > I am looking for opinions of experienced > numerical/scientific/engineering programmers along the lines of why > Fortran is a better language than C for numerical analysis. The fact that C parenthesis don't force execution order is sufficient to exclude C from use in some instances. The suggestion has been made to force execution order by introducing more temporary variables, but this costs time (to store the variables), space (for the variables), and/or additional compiler complexity (to recognize that the variables are temporaries). A really 'smart' compiler might even optimize out temporary variables and then reorder the execution. At any rate, the ability to force a particular order of expression evaluation is sometimes VERY important. It is often important in a time-critical part of the code (so extra temporaries are 'out'). The lack of SOME mechanism to do this is a deficiency in C. (Note: I don't maintain that significant parenthesis is the ONLY or even the BEST way, but to have NO WAY is certainly bad.) J. Giles Los Alamos
samperi@djs.UUCP (Dominick Samperi) (09/01/88)
In article <3064@lanl.gov> jlg@lanl.gov (Jim Giles) writes: |The fact that C parenthesis don't force execution order is sufficient |to exclude C from use [for numerical analysis] in some instances. |J. Giles |Los Alamos This is no longer true for the draft-proposed ANSI C standard (which should be adopted shortly). The following is taken from the second edition of Kernighan and Ritchie's text on C (Page 260): o A compiler's license to treat mathematically associative operators as computationally associative is revoked [in the new standard]. Other features of the new standard that may be of interest are: o All floating point values are no longer automatically converted to double in expressions; instead, values are promoted, if necessary, to the smallest capacious-enough type. o The notion of a "function prototype" is introduced. It permits the programmer to declare the data type of function formal parameters in a way that enables the compiler to check the actual parameters in each invocation of the function for type consistency. o The Standard places explicit minima on the ranges of the arithmetic types, and mandates headers (<limits.h> and <float.h>) giving the characteristics of each particular implementation. o The minimum significance of all internal identifiers is increased to 31 characters (but the smallest mandated significance of external identifiers - names of FORTRAN subroutines, for example - remains at 6 monocase letters). -- Dominick Samperi samperi@acf8.nyu.edu uunet!hombre!samperi cmcl2!acf8!samperi rutgers!acf8.nyu.edu!samperi (^ ell)
ok@quintus.uucp (Richard A. O'Keefe) (09/01/88)
In article <3064@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >The fact that C parentheses don't force execution order is sufficient >to exclude C from use in some instances. Fortran's kludge of using () to control evaluation order (which means that it has no way of expressing plain grouping *without* forcing evaluation order) has been adopted in the draft ANSI C standard, so this should cease to be a problem.
jlg@lanl.gov (Jim Giles) (09/02/88)
From article <338@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe): > Fortran's kludge of using () to control evaluation order (which means that > it has no way of expressing plain grouping *without* forcing evaluation > order) has been adopted in the draft ANSI C standard, so this should cease > to be a problem. It was proposed in a previous draft. Significant parenthesis has more recently been excluded again. (If it has been included yet again, I haven't heard yet - the committee seems about evenly split on this.) J. Giles Los Alamos
jlg@lanl.gov (Jim Giles) (09/02/88)
From article <177@djs.UUCP>, by samperi@djs.UUCP (Dominick Samperi): > o A compiler's license to treat mathematically associative operators > as computationally associative is revoked [in the new standard]. This is MORE restrictive than the significant parenthesis of Fortran. The main complaint against Fortran was that it restricted optimization too much. I haven't seen this in any of the ANSI draft standards yet. I hope I won't. J. Giles Los Alamos
ags@s.cc.purdue.edu (Dave Seaman) (09/02/88)
In article <338@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >In article <3064@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >>The fact that C parentheses don't force execution order is sufficient >>to exclude C from use in some instances. > >Fortran's kludge of using () to control evaluation order (which means that >it has no way of expressing plain grouping *without* forcing evaluation >order) has been adopted in the draft ANSI C standard, so this should cease >to be a problem. On the contrary, Fortran's parentheses control only grouping and have nothing to do with evaluation order. Consider the statement Y = A(X) + (B(X) + C(X)) where A, B and C are external functions. There are 3! = 6 possible orders of evaluation for the three functions. All six of them are legal in Fortran. For example, a perfectly legal code sequence would be the following: 1. Evaluate C(X) and place the result in a temporary, t1. 2. Evaluate A(X) and place the result in a temporary, t2. 3. Evaluate B(X) and place the result in a temporary, t3. 4. Add t3 to t2 and place the result in t3. 5. Add t3 to t1 and store the result in Y. -- Dave Seaman ags@j.cc.purdue.edu
ags@s.cc.purdue.edu (Dave Seaman) (09/02/88)
In article <3118@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >From article <177@djs.UUCP>, by samperi@djs.UUCP (Dominick Samperi): >> o A compiler's license to treat mathematically associative operators >> as computationally associative is revoked [in the new standard]. >This is MORE restrictive than the significant parenthesis of Fortran. >The main complaint against Fortran was that it restricted optimization >too much. I haven't seen this in any of the ANSI draft standards yet. >I hope I won't. I am puzzles by this. After close reading of the standard, I don't see how it is possible. Can you give an example of a Fortran expression that illustrates your claim that Fortran can treat mathematically associative operators as computationally associative? While you are at it, can you name a language that does less to inhibit optimization than Fortran? Fortran is the only language I know that prohibits modifying aliased subroutine arguments, as in REAL A(10) CALL SUB(A,A,10) . . . SUBROUTINE SUB(X,Y,N) REAL X(N), Y(N) DO 10 I=1,N T = ...something or other... Y(I) = T**2 X(I) = T 10 CONTINUE END Without this prohibition, optimization would be very difficult, as has been discussed in this group before. -- Dave Seaman ags@j.cc.purdue.edu
ok@quintus.uucp (Richard A. O'Keefe) (09/02/88)
In article <3534@s.cc.purdue.edu> ags@s.cc.purdue.edu.UUCP (Dave Seaman) writes: >In article <338@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >[I said it badly, so I shan't quote it] >On the contrary, Fortran's parentheses control only grouping and have >nothing to do with evaluation order. Oops, sorry, expressed myself badly. When writing "evaluator order" I had in mind evaluate of _operators_, not of _operands_. What I meant was that there is no method of saying "this grouping is just syntactic so that I can read the expression, mathematical laws may be applied". The point is that some expressions can't be written without using parens, and there is no way of distinguishing those parens from ones that you *want* to have the special effect. For example, unless I am mistaken, (1.0+X)*2.0 must be evaluated that way rather than as 2.0+2.0*X. Sometimes you care, but sometimes you don't. In this particular example, unless you want to do part of the calculation yourself, you have to put the parens in to get around the operator priorities. If, however, I write 2*I+2, the compiler *is* free to rearrange this as 2*(I+1). Isn't it?
jlg@lanl.gov (Jim Giles) (09/03/88)
From article <3534@s.cc.purdue.edu>, by ags@s.cc.purdue.edu (Dave Seaman): > > On the contrary, Fortran's parentheses control only grouping and have > nothing to do with evaluation order. Consider the statement > > Y = A(X) + (B(X) + C(X)) > > where A, B and C are external functions. There are 3! = 6 possible orders > of evaluation for the three functions. All six of them are legal in > Fortran. For example, a perfectly legal code sequence would be the > following: > > 1. Evaluate C(X) and place the result in a temporary, t1. > 2. Evaluate A(X) and place the result in a temporary, t2. > 3. Evaluate B(X) and place the result in a temporary, t3. > 4. Add t3 to t2 and place the result in t3. > 5. Add t3 to t1 and store the result in Y. This is simply _not_ true. Read the standard before claiming things like this. ANSI X3.9-1978 FORTRAN 77, page 6-18, line 30: In addition to the parenthesis required to establish the desired interpretation, parenthesis may be included to restrict the alternative form that may be used by the processor in the actual evaluation of the expression. This is useful for controlling the magnitude and accuracy of intermediate values developed during the evaluation of an expression. For example, in the expression A+(B-C) the term (B-C) must be evaluated and then added to A. [...] This seems pretty clear. To be sure, the three function calls in your example can be evaluated in any order. But, the result of functions B and C _must_ be added first, then added to the result of function A. J. Giles Los Alamos
fpst@hubcap.UUCP (Steve Stevenson) (09/03/88)
From article <344@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe): > > What I meant was that there is no method of saying "this grouping is > just syntactic so that I can read the expression, mathematical laws may > be applied". I'm afraid that "mathematical laws" are not numerical laws. You are not free to premute and mess with expressions because the programmer is taking great pains to keep numerical error right where he or she wants it. Minimal coding and slick optimization which produces a wrong answer for the physicist (or some )*_*&*() SDI type) won't do you any good. -- Steve Stevenson fpst@hubcap.clemson.edu (aka D. E. Stevenson), fpst@prism.clemson.csnet Department of Computer Science, comp.parallel Clemson University, Clemson, SC 29634-1906 (803)656-5880.mabell
jlg@lanl.gov (Jim Giles) (09/03/88)
From article <3535@s.cc.purdue.edu>, by ags@s.cc.purdue.edu (Dave Seaman): >>This is MORE restrictive than the significant parenthesis of Fortran. >>The main complaint against Fortran was that it restricted optimization >>too much. I haven't seen this in any of the ANSI draft standards yet. >>I hope I won't. > > I am puzzles by this. After close reading of the standard, I don't see > how it is possible. Can you give an example of a Fortran expression that > illustrates your claim that Fortran can treat mathematically associative > operators as computationally associative? You almost gave one yourself. The expression A+B+C may be evaluated as (A+B)+C, A+(B+C), or (A+C)+B. Fortran is free to do the calculation in any of those orders. But, if the original expression had been parenthesised, the order would have been required. The only associative optimization that is explicitly prohibited by the standard is violating parenthesis integrity (ANSI X3.9-1978, section 6.6.3). The processor is therefore free to do other optimizations (ANSI X3.9-1978, section 1.4). J. Giles Los Alamos
ags@s.cc.purdue.edu (Dave Seaman) (09/03/88)
In article <3534@s.cc.purdue.edu> I write: > 1. Evaluate C(X) and place the result in a temporary, t1. > 2. Evaluate A(X) and place the result in a temporary, t2. > 3. Evaluate B(X) and place the result in a temporary, t3. > 4. Add t3 to t2 and place the result in t3. > 5. Add t3 to t1 and store the result in Y. I misspoke myself in steps 4 and 5. I didn't mean to imply that Fortran was free to ignore the parentheses entirely, only that the terms could be evaluated in any order. Because of the parentheses in the original expression, steps 4 and 5 need to be changed to: 4. Add t1 and t3 and place the result in t3. 5. Add t3 and t2 and store the result in Y. -- Dave Seaman ags@j.cc.purdue.edu
jlg@lanl.gov (Jim Giles) (09/03/88)
From article <344@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe): > What I meant was that there is no method of saying "this grouping is > just syntactic so that I can read the expression, mathematical laws may > be applied". The point is that some expressions can't be written > without using parens, and there is no way of distinguishing those parens > from ones that you *want* to have the special effect. For example, > unless I am mistaken, (1.0+X)*2.0 must be evaluated that way rather than > as 2.0+2.0*X. Sometimes you care, but sometimes you don't. This is what I meant when I said that parenthesis aren't necessarily the _best_ way of doing this. But _some_ method is needed. In this respect, Fortran beats C. > [...] In This > particular example, unless you want to do part of the calculation > yourself, you have to put the parens in to get around the operator > priorities. If, however, I write 2*I+2, the compiler *is* free to > rearrange this as 2*(I+1). Isn't it? YES! Fortran _can_ optimize using the distributive rule in reverse. Maybe what's needed is a new syntax which specifies meaning without forcing order. How about {A+B}*C, which the compiler would be allowed to implement as A*C+B*C. J. Giles Los Alamos
ok@quintus.uucp (Richard A. O'Keefe) (09/03/88)
In article <2932@hubcap.UUCP> fpst@hubcap.UUCP (Steve Stevenson) writes: >From article <344@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe): >> What I meant was that there is no method of saying "this grouping is >> just syntactic so that I can read the expression, mathematical laws may >> be applied". > >I'm afraid that "mathematical laws" are not numerical laws. >You are not free to permute and mess with expressions because the >programmer is taking great pains to keep numerical error right where >he or she wants it. I know perfectly well that computer arithmetic doesn't follow the usual laws of algebra. *IF* I have taken great pains to control numerical error, then yes indeed I want it done the way I wrote it. But in that case, it is quite likely that I have given the individual parts of the expression names so that I could say things about their error bounds in my proof that this was the right way to compute the expression... But it is not the case that all Fortran code is written by, or with the aid of, numerical analysts. I haven't seen a great deal of Fortran code, but apart from statistical packages, most of the Fortran programs I've seen were written by physicists. Their Fortran expressions were derived from mathematical expressions which *DID* obey the standard algebraic laws. They had enough trouble translating their formulas into a weirdly limited character set, so the better ones coded their formulas with desk-checking in mind, _not_ numerical analysis. Now, if your floating point instructions signal overflow *and* underflow (and inexact if you've got it), and if you have well-written library packages, it's ok for the compiler to rearrange the expressions to its convenience because the programmer didn't have a particular arrangement in mind. I am not alleging that the programmer *never* has a particular arrangement in mind, only that *some* expressions are carefully ordered and *some* are not, and "(A+B)+C -because-it-must-be-done-that-way-for-numerical-reasons" and "(A+B)+C -because-that's-the-way-Thingy's-paper-wrote-the-original- formula" are different things that deserve different notation. Ideally, of course, we would have a language where the compiler could be given information about the range of variables and the criterion it would optimise in compiler-has-a-free-hand expressions would be numerical accuracy. Alternatively, some sort of preprocessor which points out possible numerical problems and suggests improvements? It seems to me that even something fairly simpleminded might at least provide a useful place to start.
samperi@djs.UUCP (Dominick Samperi) (09/03/88)
In article <3183@lanl.gov> jlg@lanl.gov (Jim Giles) writes: |The expression A+B+C may be evaluated as (A+B)+C, A+(B+C), or (A+C)+B. |Fortran is free to do the calculation in any of those orders. |J. Giles |Los Alamos I don't have a copy of the official FORTRAN standard handy, but there appears to be an inconsistency in the specifications. Specifically, most references on FORTRAN state that the primitive operators associate left to right, except for **, which associates right to left. This would imply that A+B+C will be evaluated as (A+B)+C. On the other hand, I have verified that the FORTRAN definition explicitly allows any FORTRAN implementation to rearrange the order of evaluation of an expression for optimization in any manner, provided that operator precedence rules are obeyed, and parentheses are respected. Does this not contradict the left-to-right/right-to-left rules mentioned above? I also checked into the aliasing example that was mentioned recently in this group, and the compilers I used could not detect that I was modifying the same array by two different aliases. Since rules like "functions may not have side effects that affect the result of expression evaluation" usually cannot be enforced by the compiler, they might more properly be called programming guidelines. -- Dominick Samperi samperi@acf8.nyu.edu uunet!hombre!samperi cmcl2!acf8!samperi rutgers!acf8.nyu.edu!samperi (^ ell)
ags@s.cc.purdue.edu (Dave Seaman) (09/04/88)
In article <3183@lanl.gov> jlg@lanl.gov (Jim Giles) writes: [I asked for an example of Fortran using associativity legally] >You almost gave one yourself. The expression A+B+C may be evaluated >as (A+B)+C, A+(B+C), or (A+C)+B. Fortran is free to do the calculation >in any of those orders. Well, ok, that's technically an application of associativity, but it's not exactly what I had in mind. The only reason you are allowed to write A+B+C in the first place, rather than (A+B)+C or A+(B+C), is that you are assuming associativity and therefore you are telling the compiler that it doesn't matter. -- Dave Seaman ags@j.cc.purdue.edu
fpst@hubcap.UUCP (Steve Stevenson) (09/05/88)
From article <349@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe): > In article <2932@hubcap.UUCP> fpst@hubcap.UUCP (Steve Stevenson) writes: >>From article <344@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe): > But it is not the case that all Fortran code is written by, or with the > aid of, numerical analysts. ... Richard: As usual, you and I are not communicating. The question at hand is whether or not Fortran should be the way it is for (see Subject) numerical analysis. I agree that much fortran is written by not NAs. I also believe, given your background, you will agree that there are two problems: getting physicists to write proper numerical code and not impeding NAs from writing proper code. Why doesn't Quintus take that up --- should be a straight forward problem if PRESS ever is released :-). I certainly respect your opinion. It seems a poor choice of action to perpetuate the use of Fortran for the business folks and for comp. sci. majors who do not have the background to translate from their very limited understanding of the axiomatic reals into the real world of floating point. The myth that anybody can code was debunk quite a while ago. -- Steve Stevenson fpst@hubcap.clemson.edu (aka D. E. Stevenson), fpst@prism.clemson.csnet Department of Computer Science, comp.parallel Clemson University, Clemson, SC 29634-1906 (803)656-5880.mabell
shenkin@cubsun.BIO.COLUMBIA.EDU (Peter Shenkin) (09/06/88)
+ In article <3064@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
+
+ >From article <893@amelia.nas.nasa.gov>,
+ > by fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts):
+ >> I am looking for opinions of experienced
+ >> numerical/scientific/engineering programmers along the lines of why
+ >> Fortran is a better language than C for numerical analysis.
+
+ >The fact that C parenthesis don't force execution order is sufficient
+ >to exclude C from use in some instances.....
I believe that under the new C standard, parentheses will force order of
evaluation. This replaces a previous provision that used unary + for the
same purpose.
--
*******************************************************************************
Peter S. Shenkin, Department of Chemistry, Barnard College, Columbia University
New York, NY 10027 Tel: (212) 280-5517 (work); (212) 829-5363 (home)
shenkin@cubsun.bio.columbia.edu shenkin%cubsun.bio.columbia.edu@cuvmb.BITNET
peter@ficc.uu.net (Peter da Silva) (09/08/88)
The compiler is free to perform any optimisation it wants, so long as it doesn't change the result. So (1.0+x)*2.0 can be evaluated as 2+2*x if that's more efficient. Multiplying by 2 is an exact operation in binary floating point. -- Peter da Silva `-_-' Ferranti International Controls Corporation. "Have you hugged U your wolf today?" peter@ficc.uu.net
jlg@lanl.gov (Jim Giles) (09/09/88)
From article <1421@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): > The compiler is free to perform any optimisation it wants, so long as > it doesn't change the result. So (1.0+x)*2.0 can be evaluated as 2+2*x > if that's more efficient. Multiplying by 2 is an exact operation in > binary floating point. This was just a badly chosen example. Suppose the expression had been: (1.2345+x)*6.7890? Applying the distributive law to this doesn't produce the same computational result. The question is: should the optimization be allowed anyway? The rules of Fortran don't allow it, the rules of C (there are rules in C?) do. The problem with C is that it provides _no_ way to force a given order of expression evaluation (ANSI doesn't count - expression ordering of one kind or another has been proposed and removed so many times that there is no way of telling whether the final standard will have the feature or not). J. Giles Los Alamos
fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (09/09/88)
In article <3349@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >The problem with C is that >it provides _no_ way to force a given order of expression evaluation I can't let you get away with this. _no_ way is very strong. C allows you to break the expression up into subexpressions, calculate the subexpressions into temporary variables and then combine the temps into the final expression. If you don't run the optimizer on this code, you are going to get exactly what you express. (;-) Marty +-+-+-+ I don't know who I am, why should you? +-+-+-+ | fouts@lemming.nas.nasa.gov | | ...!ames!orville!fouts | | Never attribute to malice what can be | +-+-+-+ explained by incompetence. +-+-+-+
fpst@hubcap.UUCP (Steve Stevenson) (09/09/88)
From article <976@amelia.nas.nasa.gov>, by fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts): > C allows you to break the expression up into subexpressions, calculate > the subexpressions into temporary variables and then combine the temps > into the final expression. Back in the Jurassic age, Knuth (I think) wrote an article which pointed out that most expressions are very short when occuring in assignment statements. I could believe the above was the reason. But the point is --- Why in the name of science do I have to hack. I thought we were trying to get away from that. What's wrong with C recogizing that floating point arithmetic is not real arithmetic and observing the rules. EXAMPLE: the easiest rip-off scheme in DP is to pick up the fuzz from interest calculations and put it in your account. I certainly would never try to convince the business types that that occurs. I rather let them figure it out. Star Wars --- that's a different issue.-- Steve Stevenson fpst@hubcap.clemson.edu (aka D. E. Stevenson), fpst@prism.clemson.csnet Department of Computer Science, comp.parallel Clemson University, Clemson, SC 29634-1906 (803)656-5880.mabell
samperi@marob.MASA.COM (Dominick Samperi) (09/09/88)
In article <3349@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >the rules of C (there are rules in C?) do. The problem with C is that >it provides _no_ way to force a given order of expression evaluation But you criticized C (ANSI C) for forcing a left-to-right evaluation order in expressions like a+b+c+d in a previous posting. The beauty of C stems from the mathematical consistency of its rules; the new (strict) associativity rules for mathematical expressions is a natural extension of the associativity rules for the non-mathematical C operators, which enable the programmer to predict exactly how an expression will be evaluated. True, ANSI C is not yet an "official" standard, but neither is the current C, yet the current language has undergone very few changes in 10+ years of use. I maintain that the reason for this remarkable stability is the mathematical consistency of the language, together with its fine data structuring capabilities, and its low-level features (which facilitate the design of portable code). ANSI conformant C compilers are already in existence, and I suspect that most C compilers will conform to this standard in the near future, even if the standard is never published! (Well, one might say that it has already been published, in the Second Edition of K&R's text, which has been the definitive working standard for the last 10 years.) I'm sure that the new FORTRAN standard will address many of the shortcommings of the language: no support for data abstraction (no data structuring tools), no support for information hiding (all function identifiers are globally accessible), no recursion, identifiers limited to 6 characters, automatic variable typing via the "first letter rule," ambiguous or inconsistent specs. (the simple operators associate left-to-right, except for **, which associates right-to-left, but forget this because the compiler can do what it pleases for optimization...), programming guidelines made part of the language spec., etc. Unfortunately, last I heard was that this new FORTRAN standard is not likely to appear for a long time, due to the inability of the committee to agree on anything. -- Dominick Samperi, NYC samperi@acf8.NYU.EDU samperi@marob.MASA.COM cmcl2!phri!marob uunet!hombre!samperi (^ ell)
peter@ficc.uu.net (Peter da Silva) (09/10/88)
Hi Jim... you should meet Mr. Rubin over in comp.lang.c. In article <3349@lanl.gov>, jlg@lanl.gov (Jim Giles) writes: > From article <1421@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): > > ...(1.0+x)*2.0 can be evaluated as 2+2*x... > This was just a badly chosen example. Suppose the expression had been: > (1.2345+x)*6.7890? Applying the distributive law to this doesn't > produce the same computational result. No. > The question is: should the optimization be allowed anyway? No. > The rules of Fortran don't allow it, the rules of C (there are rules in C?) > do. The rules of ANSI X3J11 do require that this optimisation not be taken. > The problem with C is that > it provides _no_ way to force a given order of expression evaluation Yes, this is a shortcoming addressed by ANSI X3J11. Other shortcomings addressed by this standard (and shared, by the way, by Fortran) include such things as the lack of function prototyping and a guaranteed method for handling I/O devices and other asynchronous processing (volatile). > (ANSI doesn't count - expression ordering of one kind or another has > been proposed and removed so many times that there is no way of telling > whether the final standard will have the feature or not). Given the fact that it's now in the final stages, and only editorial changes are allowed (as in, this or that wording is unclear...), it's highly unlikely that it will be removed. -- Peter da Silva `-_-' Ferranti International Controls Corporation. "Have you hugged U your wolf today?" peter@ficc.uu.net
jlg@lanl.gov (Jim Giles) (09/11/88)
From article <408@marob.MASA.COM>, by samperi@marob.MASA.COM (Dominick Samperi): > In article <3349@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >>the rules of C (there are rules in C?) do. The problem with C is that >>it provides _no_ way to force a given order of expression evaluation > > But you criticized C (ANSI C) for forcing a left-to-right evaluation order > in expressions like a+b+c+d in a previous posting. The beauty of C stems > [... I have never criticized C (either ANSI or K&R) for forcing strict left to right ordering. Neither makes that requirement. I the most recent version of the ANSI standard _does_ make that constraint, I'm opposed! Allowing _no_ optimization is as bad as not constraining optimization. There should be a middle ground which allows the compiler to optimize in most cases but allows the user to enforce a particular order in those cases where it's important to do so. > from the mathematical consistency of its rules; the new (strict) What consistency? There are deliberately ambiguous features in C. Not just in expression ordering, but in assignment ordering. For example: what is the value of i after the expression i=f(i++)? Both ANSI and K&R say this is undefined but _not_ illegal. And this is the language you claim is consistent? > I'm sure that the new FORTRAN standard will address many of the shortcommings > [...] > specs. (the simple operators associate left-to-right, except for **, which > associates right-to-left, but forget this because the compiler can do > what it pleases for optimization...), programming guidelines made part > of the language spec., etc. Exponentiation is _not_ associative so I don't know what you're telling me about the 'compiler can do what it pleases'. Operators which _are_ associative may be optimized using this fact as long as the integrity of parenthesis is observed. This has been around (and _well_ understood) for much longer than C has even existed. It's only C programmers who complain about this rule, many even claim not to understand it. Most other programming languages follow the same rule as Fortran. It is a good rule. C has no such rule. By the way, just out of curiosity, what 'programming guidelines' are part of the Fortran language spec? I've got the standard right here and I can't find any. > Unfortunately, last I heard was that this new FORTRAN standard is not likely to > appear for a long time, due to the inability of the committee to > agree on anything. The same might be said of the C committee. C is out for its _third_ public review (Fortran has only had one so far). And so far the C committee hasn't addressed many of the shortcommings of the K&R version (like deliberate ambiguities in the semantics, conflicting operator precidence rules (the worst are the unary prefix and postfix operators some of which have high precidence and some of which have lower precidence), arcane declaration syntax, etc.). None of this even mentions the unreadable terse syntax, the lack of even the _concept_ of an array (the array syntax is instantly turned into pointers - there is no semantic concept of arrays), and no floating-point arithmetic (ANSI will supposedly introduce it, but C has previously been _all_ double precision), the lack of complex data type (macros are inherently slower and less optimizable, other patches for complex are even less attractive), etc.. J. Giles Los Alamos
samperi@marob.MASA.COM (Dominick Samperi) (09/12/88)
In article <3417@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >> from the mathematical consistency of its rules; the new (strict) >What consistency? There are deliberately ambiguous features in C. Not >just in expression ordering, but in assignment ordering. For example: >what is the value of i after the expression i=f(i++)? Both ANSI and K&R >say this is undefined but _not_ illegal. And this is the language you >claim is consistent? This ambiguity is easily avoided by following the rule: "a variable that is auto-incremented/decremented should never appear on both sides of the '=' operator." One might compare this rule to the FORTRAN: "do not modify the same array by two different aliases," since both rules have in common the fact that the compiler will not make sure you obey them (though FORTRAN compilers are supposed to catch this error, I haven't seen any that do). This is the programming guideline that I was referrring to in my previous posting. >terse syntax, the lack of even the _concept_ of an array (the array syntax >is instantly turned into pointers - there is no semantic concept of arrays), C and FORTRAN handle arrays similarly, though you are permitted to do more with an array in C than you can in FORTRAN (like manipulate its address explicitly). And of course, the rows/columns are stored differently in the two languages, but I wouldn't conclude from this that C does not support the array concept. An array can be used in C just like it would be in FORTRAN (with the rows/columns reversed); there is no need to use the lower- level capabilities of C. And when arrays are passed to functions, a pointer is passed in both languages. I am not arguing that C is necessarily a good language to use for numerical analysis (which was the question that started this discussion), but I do feel that FORTRAN needs some work: should be able to hide the names of internal package function names, some data structuring facility is needed, the 6-letter restriction should be removed, the compiler should require that all variable names be explicitly declared (or at least support the VMS IMPLICIT NONE feature), more flexible comment syntax would be nice, and a standardized macro facility would help to patch up other blemishes. -- Dominick Samperi, NYC samperi@acf8.NYU.EDU samperi@marob.MASA.COM cmcl2!phri!marob uunet!hombre!samperi (^ ell)
jlg@lanl.gov (Jim Giles) (09/13/88)
From article <410@marob.MASA.COM>, by samperi@marob.MASA.COM (Dominick Samperi): > This ambiguity is easily avoided by following the rule: "a > variable that is auto-incremented/decremented should never appear on > both sides of the '=' operator." Who's putting programming guidlines into a language _now_? Why can't C make the above rule part of the standard and have done with it? That way the compiler could check for this error (and, it really is an error in every use I've ever seen). The alias rule in Fortran is indeed comparable (as you pointed out), and Fortran correctly rules this to be illegal (even though aliased arrays are more difficult to check). C doesn't outlaw aliased arrays either (thgat's why dynamically allocated multi- dimensional arrays don't optimize well in C - they are implemented as an array of pointers which _can_ point to aliased areas of memory). This is, by the way, what I mean when I say that C doesn't have the concept of array (that is, a one or more dimensional collection of data of identical type, no part of which is aliased to any other part). Fortran extensions to allow dynamic memory all implement multidimensional dynamic arrays the same as statically allocated arrays - the optimizer doesn't have to assume that aliasing is possible so it does better than C does. (Note: the Fortran 8x proposal for allocatable arrays follows this rule as well.) J. Giles
cik@l.cc.purdue.edu (Herman Rubin) (09/13/88)
One deficiency in FORTRAN which is corrected in C is the ability to use a variable pointer. If this is wanted, it can be a major headache in FORTRAN to find a way around it. -- Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907 Phone: (317)494-6054 hrubin@l.cc.purdue.edu (Internet, bitnet, UUCP)
davis@galaxy.ee.rochester.edu (Al Davis) (09/13/88)
In article <3417@lanl.gov> jlg@lanl.gov (Jim Giles) writes......: >(comments on consistency, expressions like i=f(i++), etc. To catch all possiblilites is impossible. To restrict this kind of thing would unnecesarily cripple the language, and make it harder to read. It is up to the coder to code clearly. >(in response to comment that Fortran commitee can't agree on anything) >The same might be said of the C committee. C is out for its _third_ >public review (Fortran has only had one so far). Only one because they can't...... at least the C committee publishes >(comments on the unary syntax, C is cryptic, etc.) Any language is cryptic if you don't know it. I like the C terse syntax. I find it interesting that Fortran users who complain loudest about often are mathematicians who use lots of terse, cryptic math notation in their writings. The reason is clear: terse is easier to read, if you know the language. It is unfortunate that much of the code written is of poor quality, but that is not an indication that the language is poor. It seems all languages have their share. >the lack of even the _concept_ of an array (the array syntax >is instantly turned into pointers - there is no semantic concept of arrays), Fortran and C handle arrays in almost the same way, if you insist. C programmers rarely do it that way, because the pointer and dynamic allocation approach is much more flexible. If you understand C's dynamic allocation, Fortran's conformant arrays look painfully error prone and primitive. If you want to look at it this way, Fortran has no semantic concept of a CONSTANT. oops. >(no single precision, no complex, etc.) C does have some faults. I wish ANSI would fix it. C++ fixes it, and more. The no single precision (actually there is single precision, but the type conversions often eliminate the speed advantages, and ANSI did fix this. I never use single precision anyway, it is not accurate enough.) is a consequence of two bad moves: portability at the expense of function, and taking K&R too literally. >J. Giles >Los Alamos I am curious why Ratfor isn't used more. I think I know the real reason, and it isn't portability. Albert Davis University of Rochester
peter@ficc.uu.net (Peter da Silva) (09/13/88)
In article <3445@lanl.gov>, jlg@lanl.gov (Jim Giles) writes: > Why can't C make the above rule part of the standard and have done with it? Because putting it in doesn't enhance the utility of the language? You can't possibly outlaw every peice of bad progframming practice. That way lies ADA. > C doesn't > outlaw aliased arrays either (thgat's why dynamically allocated multi- > dimensional arrays don't optimize well in C - they are implemented as > an array of pointers which _can_ point to aliased areas of memory). You mean dynamically sized arrays. Dynamically allocated but statically sized arrays are implemented like any other array. > This is, by the way, what I mean when I say that C doesn't have the > concept of array (that is, a one or more dimensional collection of > data of identical type, no part of which is aliased to any other part). Sure it does. You just can't size it dynamically. -- Peter da Silva `-_-' Ferranti International Controls Corporation. "Have you hugged U your wolf today?" peter@ficc.uu.net
hjm@cernvax.UUCP (Hubert Matthews) (09/13/88)
Consider the following cases: I = (5 / 4) * 5 (I gets 5) I = 5 / (4 * 5) (I gets 0) I = 5 / 4 * 5 (I gets 5 in F77, I gets something in C) Personally, I wouldn't use case 3; I would always enforce an evaluation order by using parentheses. If this could be ambiguous in C, I wouldn't use it for numerical work. The same problem occurs when using mixed-mode arithmetic. Evaluation order is important, and parentheses are the most obvious way of expressing it. Temporary variables are a hack. Hubert Matthews
samperi@djs.UUCP (Dominick Samperi) (09/13/88)
In article <3445@lanl.gov> jlg@lanl.gov (Jim Giles) writes: |that's why dynamically allocated multi- |dimensional arrays don't optimize well in C - they are implemented as |an array of pointers which _can_ point to aliased areas of memory). The emphasis on _can_ is important here, for C permits many freedoms that you need not use for routine numerical applications. Arrays can be declared or created at runtime that are no different from FORTRAN arrays (except that the rows/columns are swapped); there is no need to use any tricks that result in obscure aliasing. It is true though that because of the freedoms, the compiler may not be able to optimize the way it does for FORTRAN arrays (how does it do this, by the way?). The use of the autoincrement/decrement operators might be classified along with these aliasing tricks and other lower-level C constructs as "advanced" features of the language, and avoided entirely in numerical applications. Then obscure code like while(*dest++ = *source++) ; could be written like this instead: i = 0 ; while(source[i] != 0) { dest[i] = source[i] ; i = i + 1 ; } dest[i] = 0 ; This would also rule out those tricky expressions of the form b[i] = a[i++], for example. On the other hand, using some of the low-level features might be useful at times. For example, a lower-triangular matrix a[i][j], j <= i, can be created, where memory is not allocated for the zero elements above the diagonal. A more exotic example might be one where it is possible to arrange for the various rows of a matrix to be allocated in different memory modules/banks. This functionality could easily be added to FORTRAN by simply providing a standardized macro facility. -- Dominick Samperi samperi@acf8.nyu.edu uunet!hombre!samperi cmcl2!acf8!samperi rutgers!acf8.nyu.edu!samperi (^ ell)
jlg@lanl.gov (Jim Giles) (09/14/88)
From article <1454@valhalla.ee.rochester.edu>, by davis@galaxy.ee.rochester.edu (Al Davis): > Any language is cryptic if you don't know it. I like the C terse syntax. > I find it interesting that Fortran users who complain loudest about often > are mathematicians who use lots of terse, cryptic math notation in their > writings. [...] This is a discussion about programming for numerical analysis. I would argue that if any terse syntax is used at all, it should be the one that mathematicians and physicists use - not a new one invented from the strange mind of an AT&T type. If you can't do the terse syntax that is really used by mathemeticians, you shouldn't have a terse syntax at all. But that wasn't my complaint about C. The C syntax is not desireable because the operator precidence doesn't follow any sensible rules. For example, left-to-right would imply that prefix operators should have higher precidence than postfix - that's not how it was done though. > never use single precision anyway, it is not accurate enough.) [...] Single precision on the Cray carries 48 bits of precision and 15 bits of exponent. That's more than accurate enough for any work presently being done on those toy VAXen. J. Giles Los Alamos
lfm@fpssun.fps.com (Larry Meadows) (09/14/88)
In article <410@marob.MASA.COM>, samperi@marob.MASA.COM (Dominick Samperi) writes: > [...] FORTRAN: "do not modify the same array > by two different aliases," since both rules have in common the fact that > the compiler will not make sure you obey them (though FORTRAN compilers > are supposed to catch this error, I haven't seen any that do). I know we have beaten this dead horse to death, but I just can't resist. The FORTRAN ANSI-77 standard says that the behavior in this case is undefined. It does not, repeat not, ..., repeat not state, imply, or suggest that a compiler is required to detect this error, any more than it is required to detect assignment to a constant passed as an actual parameter, different length common blocks with the same name, ad nauseum. What it means is that a standard-conforming compiler can assume that these rules are not violated and perhaps optimize the code better as a result. Of course, some of these rules are violated so often that compiler writers, to satisfy their users, must treat the violations as de facto extensions to the standard. -- Larry Meadows @ FPS ...!tektronix!fpssun!lfm ...!nosun!fpssun!lfm
jlg@lanl.gov (Jim Giles) (09/14/88)
From article <1484@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): > You mean dynamically sized arrays. Dynamically allocated but statically > sized arrays are implemented like any other array. No, I've never seen a C dynamically allocated multidimensional array that wasn't implemented as an array of pointers. For a two dimensional array, each pointer in the array of pointers points to a row of the array. Higher dimensions are implementes as pointers_to_pointers_to_.... the number of indirect levels is one less than the number of dimensions. - This is _NOT_ 'like any other array'. J. Giles Los Alamos
chris@mimsy.UUCP (Chris Torek) (09/14/88)
>In article <1484@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: >>You mean dynamically sized arrays. Dynamically allocated but statically >>sized arrays are implemented like any other array. In article <3502@lanl.gov>, jlg@lanl.gov (Jim Giles) writes: >No, I've never seen a C dynamically allocated multidimensional array >that wasn't implemented as an array of pointers. For a two dimensional >array, each pointer in the array of pointers points to a row of the array. >Higher dimensions are implementes as pointers_to_pointers_to_.... >the number of indirect levels is one less than the number of dimensions. > >- This is _NOT_ 'like any other array'. You seem to have conveniently forgotten the material I posted here not long ago. Here is a dynamic (fixed size) array that is not an array of pointers: extern char *malloc(); f() { double (*arr)[64]; int n_rows = 16, i, j; arr = (double (*)[64])malloc(n_rows * sizeof(*arr)); if (arr == NULL) ... do something for (i = 0; i < n_rows; i++) for (j = 0; j < 64; j++) /* work on arr[i][j] */; } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
davis@galaxy.ee.rochester.edu (Al Davis) (09/14/88)
In article <3502@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >From article <1484@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): >> You mean dynamically sized arrays. Dynamically allocated but statically >> sized arrays are implemented like any other array. > >No, I've never seen a C dynamically allocated multidimensional array >that wasn't implemented as an array of pointers. Well, what is wrong with an array of pointers? Having worked with both, I believe the array of pointers is the superior method. It eliminates the conformant array fudge. It is usually faster. It is more general. It works for strangely shaped sparse matrices. Etc. All the world is not a Cray. Some of us have to work with finite resources. Al Davis
chris@mimsy.UUCP (Chris Torek) (09/14/88)
In article <183@djs.UUCP> samperi@djs.UUCP (Dominick Samperi) writes: >The emphasis on _can_ is important here .... Indeed. >[some features] might be classified ... as "advanced" features >of the language, and avoided entirely in numerical applications. Alas, unless there were some way to signal to the compiler that this were the case, or unless it were obvious, it would not help the compiler generate better code. (Fortunately, what is `obvious' is growing by leaps and bounds in compiler technology. Cross-module optimisation is no longer considered `too hard'. I predict that decent alias detection will soon not be considered `too hard' either. [Never mind that it is in some sense impossible: so is loop optimisation, in the presense of irreducible flow graphs, yet compilers do that today.]) > while(*dest++ = *source++) ; > >could be written like this instead: > > i = 0 ; > while(source[i] != 0) > { > dest[i] = source[i] ; > i = i + 1 ; > } > dest[i] = 0 ; Any half-decent optimiser should have no trouble converting the former to the latter (with `source += i, dest += i' added). (This assumes that the latter is more efficient. Typically optimisers have had to convert the latter to the former.) I do suggest, though, that no one use `i = i + 1' to increment. If you dislike `++', use `i += 1'. When you mean `add one to i', why not *say* it? -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
jlg@lanl.gov (Jim Giles) (09/15/88)
From article <13547@mimsy.UUCP>, by chris@mimsy.UUCP (Chris Torek): > I do suggest, though, that no one use `i = i + 1' to increment. If you > dislike `++', use `i += 1'. When you mean `add one to i', why not *say* > it? 'i = i + 1' _does_ say it!!! Any compiler which generates different code for 'i = i + 1', 'i += 1', and 'i++' is a certifiably _stupid_ compiler. Those three examples are semantically _identical_, their syntactic difference is a textual convenience - at best. J. Giles Los Alamos
jlg@lanl.gov (Jim Giles) (09/15/88)
From article <1457@valhalla.ee.rochester.edu>, by davis@galaxy.ee.rochester.edu (Al Davis): > Well, what is wrong with an array of pointers? Having worked with both, I > believe the array of pointers is the superior method. It eliminates the ^^^^^^^^^^^^^^^ > conformant array fudge. It is usually faster. It is more general. It ^^^^^^^^^^^^^^^^^^^^ > works for strangely shaped sparse matrices. Etc. I agree with everything above except the marked portions. If I want an array of pointers to pointers to ..., I should do something different from just declaring a two dimensional array - arrays of pointers aren't the same! For one thing, they are almost always slower - they can _never_ be faster because a conformant array _can_ be implemented that way if necessary. An array of pointer to pointer to ... _can't_ be treated as a conformant array though - some of the pointers might be aliased! The fact that they usually aren't doesn't help, the optimizer must assume that it's possible. Someone claimed that interprocedural alias detection will soon be simple - I haven't seen it yet. In any case, even inter- procedural analysis doesn't help if the array isn't constructed until run-time - the compiler can only do things like unrolling loops if it knows _at_compile_time_ that there are no aliased arrays involved. In short, any optimization possible for arrays of pointer to... is also possible for conformant arrays. The reverse is _not_ true. Admittedly, the pointers are more powerful and more general, but if your application doesn't need the power or generality of pointers, you probably would prefer the more optimal conformant arrays. Indeed, it's possible to extend Fortran to include pointers (the Fortran I use has them), it's very difficult to get conformant arrays in C - even when that's what you really want! J. Giles Los Alamos
fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (09/15/88)
In article <3502@lanl.gov> jlg@lanl.gov (Jim Giles) writes: > >No, I've never seen a C dynamically allocated multidimensional array >that wasn't implemented as an array of pointers. For a two dimensional >array, each pointer in the array of pointers points to a row of the array. >Higher dimensions are implementes as pointers_to_pointers_to_.... >the number of indirect levels is one less than the number of dimensions. > >- This is _NOT_ 'like any other array'. Jim, here's one: main() { float x[10][10]; fprintf(stdout,"Hi Jim!\n"); exit(0); } Most C compilers will generate the same kind of 2d array code for this as any other language with adjacently spaced arrays. The array qualifies as dynamic, since it is local/automatic and gets allocated on the stack when the procedure is run. (;-) I think various people are quibbling over poor definitions at this point. Fortran doesn't support dynamic arrays -- in the sense of space allocated at runtime -- at all. (Well, it didn't before the "SAVE" statement introduced the possiblility of recursion. Now it does.) C supports two different kinds of dynamic arrays: Call stack allocated and memory allocator returned. Fortran doesn't support memory allocator returned. (No pointers) The above is an example of call stack allocated. memory allocator returned is slightly different. Fortran does support conformant arrays (sort of) in subroutine references This SUBROUTINE A(X,N,M) DIMENSION X(N,M) is legal, but this SUBROUTINE A(X,N,M) DIMENSION X(N,M), Y(N,M) is not. This has been the cause of considerable grief to Fortran programers over the years. C only sort of has conformant arrays. The C declaration suba(x) real x[][N]; is a sort of conformant C array. C lets you get away with one dimension being unspecified, but requires you specify the others. Conformant local arrays are also quite illegal in C. It is true that C compilers can't generate efficent code in the general case of memory allocated dynamic arrays, but Fortran compilers can't generate any code at all. (;-) Further, C compilers can, and some do, generate good code when they detect explicit dope vectors. In order to avoid the math of index calculation, many compilers generate offset index vectors. There is a C idiom (See Numerical Recipes in C's appendices for an example) which looks exactly like a dope vector. At least one compiler I am aware of can sometimes detect and always be told that a dynamic array is of this form, allowing the compiler to generate exactly the code you would expect for a contiguously allocated array. Neither language has all of the features that I could use for arrays in numerical work. A partial list (off the top of my head) includes: o Range specification, ala Pascal's [n..m] format. o The ability to query an array for its shape. By shape, I mean the number of indices and the ranges of each index. o not having to specify the shape of an array when it is passed as an argument. o True dynamic (all senses) multiple dimensioned arrays in subroutines. o good checking for uninitialized reference errors and index out of bound errors which I can selectively enable at runtime. o reduction operators (;-) With respect to array semantics, Fortran is very good in the presences of vector machines and naive compiler technology. C is very good for dynamically varying requirements in memory tight environments. I can easily make C behave like Fortran for many applications; I have a great deal of trouble going the other way. Marty +-+-+-+ I don't know who I am, why should you? +-+-+-+ | fouts@lemming.nas.nasa.gov | | ...!ames!orville!fouts | | Never attribute to malice what can be | +-+-+-+ explained by incompetence. +-+-+-+
lamaster@ames.arc.nasa.gov (Hugh LaMaster) (09/15/88)
In article <1484@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: >You mean dynamically sized arrays. Dynamically allocated but statically >sized arrays are implemented like any other array. >> This is, by the way, what I mean when I say that C doesn't have the >> concept of array (that is, a one or more dimensional collection of >Sure it does. You just can't size it dynamically. I still consider the lack of dynamically SIZED arrays to be a major stumbling block for the acceptance of C for numerical analysis. I do not accept that applications programmers should have to deal constantly with arrays of pointers just to get this capability. But then, I believe that pointers should be used as a LAST RESORT in APPLICATIONS code, unlike REAL programmers who eat arrays of pointers to functions for breakfast :-) -- Hugh LaMaster, m/s 233-9, UUCP ames!lamaster NASA Ames Research Center ARPA lamaster@ames.arc.nasa.gov Moffett Field, CA 94035 Phone: (415)694-6117
chris@mimsy.UUCP (Chris Torek) (09/15/88)
>In article <1457@valhalla.ee.rochester.edu> davis@galaxy.ee.rochester.edu >(Al Davis) writes: >>Well, what is wrong with an array of pointers? Having worked with both, I >>believe the array of pointers is the superior method. It eliminates the > ^^^^^^^^^^^^^^^ >>conformant array fudge. It is usually faster. It is more general. It > ^^^^^^^^^^^^^^^^^^^^ >>works for strangely shaped sparse matrices. Etc. In article <3570@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >I agree with everything above except the marked portions. Good so far. >If I want an array of pointers to pointers to ..., I should do something >different from just declaring a two dimensional array - arrays of pointers >aren't the same! You have just described C declarations. >For one thing, they are almost always slower - they can _never_ ^^^^^^^^^^^^^^^^^^^^ >be faster because a conformant array _can_ be implemented that way if >necessary. An array of pointer to pointer to ... _can't_ be treated >as a conformant array though - some of the pointers might be aliased! It is true that they can never be faster. Saying that they are `almost always slower', however, shows just as much bias as Al Davis's claim. >The fact that they usually aren't doesn't help, the optimizer must assume >that it's possible. Someone claimed that interprocedural alias detection >will soon be simple - I haven't seen it yet. Of course not. When I said `soon' I meant `on the order of 10 years'. (This is certainly not `soon enough' for those doing this sort of work now.) >... Indeed, >it's possible to extend Fortran to include pointers (the Fortran I use >has them), it's very difficult to get conformant arrays in C - even >when that's what you really want! Indeed, it is possible to extend C to include conformant arrays (the C I use has them%); it is very difficult to get pointers in Fortran---even when that is what you really want! ----- % Well, actually, I do not use it. It is GCC, available for free from prep.ai.mit.edu and other places on the Internet. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
chris@mimsy.UUCP (Chris Torek) (09/15/88)
In article <820@cernvax.UUCP> hjm@cernvax.UUCP (Hubert Matthews) writes: >Consider the following cases: > > I = (5 / 4) * 5 (I gets 5) > > I = 5 / (4 * 5) (I gets 0) > > I = 5 / 4 * 5 (I gets 5 in F77, I gets something in C) I gets 5 in C (even in K&R 1st ed. C). The arithmetic operators group left-to-right, and while The order of evaluation is not specified for associative and commutative operators like * and + (K&R 1st ed., p. 37), the divide operator is hardly commutative! >Evaluation order is important, and parentheses are the most obvious way of >expressing it. Temporary variables are a hack. Sometimes (many people will break up ten-line expressions for the sake of clarity). Nonetheless, there are two problems being solved: overriding the default groupings, and specifying order of operation. Any time you use a single solution for two (or more) orthogonal problems, you have missed out on some potential orthogonality. (Whether it would in fact be *useful* is a different argument entirely.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
ok@quintus.uucp (Richard A. O'Keefe) (09/15/88)
In article <820@cernvax.UUCP> hjm@cernvax.UUCP (Hubert Matthews) writes: > I = 5 / 4 * 5 (I gets 5 in F77, I gets something in C) > >Personally, I wouldn't use [this]; I would always enforce an evaluation order >by using parentheses. If this could be ambiguous in C, I wouldn't use it for >numerical work. This is not ambiguous in C, and never has been. % echo "I = 5 / 4 * 5;" | cparen I = ((5 / 4) * 5); In fact, this is one of the reasons why some C programmers resent the Fortran people telling them what to do with parentheses: C programmers are used to adding parentheses to expressions to clarify the grouping *without* changing the semantics. The point at issue is whether I = N * P * Q; and I = (N * P) * Q; have the same meaning. In pre-ANSI C, they did; a compiler could rearrange both. In the current draft, the two expressions are different, exactly as in Fortran.
ok@quintus.uucp (Richard A. O'Keefe) (09/15/88)
In article <14897@ames.arc.nasa.gov> lamaster@ames.arc.nasa.gov.UUCP (Hugh LaMaster) writes: >I still consider the lack of dynamically SIZED arrays to be a major stumbling >block for the acceptance of C for numerical analysis. "Algol 60 is an improvement on its successors". Still true. But if the lack of dynamically sized arrays didn't stop Fortran, why complain about C? Array parameters are another matter. Fortran has such ``real'' arrays that DIMENSION A(10) CALL KLUDGE(A(5), 6) END SUBROUTINE KLUDGE(B, N) DIMENSION B(N) B(1) = 0.0 B(N) = 0.0 RETURN END is a legal program. Is A(5) a scalar or an array? Well, yes, sort of. I hope *some* of the things that were going to be in Fortran 8X make it into a standard fairly soon. I was looking forward to having decent arrays. [Why should we an exception library be "language-independent", when we haven't even got a "language-independent" notion of arrays?]
peter@ficc.uu.net (Peter da Silva) (09/15/88)
In article <3502@lanl.gov>, jlg@lanl.gov (Jim Giles) writes: > From article <1484@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): > > You mean dynamically sized arrays. Dynamically allocated but statically > > sized arrays are implemented like any other array. > No, I've never seen a C dynamically allocated multidimensional array > that wasn't implemented as an array of pointers. char (*twodarray)[10][10]; twodarray = malloc(sizeof(*twodarray)); (*twodarray)[10][5] = 'c'; Now you have. -- Peter da Silva `-_-' Ferranti International Controls Corporation. "Have you hugged U your wolf today?" peter@ficc.uu.net
ags@h.cc.purdue.edu (Dave Seaman) (09/15/88)
In article <406@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: [ explaining that a particular expression is not ambiguous in C ] >In fact, this is one of the reasons why some C programmers resent the >Fortran people telling them what to do with parentheses: C programmers >are used to adding parentheses to expressions to clarify the grouping >*without* changing the semantics. The point at issue is whether > I = N * P * Q; >and I = (N * P) * Q; >have the same meaning. In pre-ANSI C, they did; a compiler could >rearrange both. In the current draft, the two expressions are different, >exactly as in Fortran. What are you afraid of? What problem does it cause if the compiler decides to respect the extra parentheses that you put in for no reason? After all, even in C under the K&R standard, there is no guarantee that the compiler will NOT treat the expression differently because of the parentheses. If all you are interested in is emphasizing grouping for the benefit of the human reader, you can do that quite effectively by the proper use of white space. You don't need parentheses. In fact, white space works BETTER than parentheses for this purpose. Compare: t = a*cos(x) + b*cos(y) + c*f(x-y) + d*f(x+y) with t=((a*cos(x))+(b*cos(y)))+((c*f(x-y))+(d*f(x+y))) -- which would you rather read? In the expression "(A*B)*C", suppose A and C are large enough that the product causes overflow, while B is small enough that the expression can be evaluated sensibly, provided the compiler does not rearrange it to "(A*C)*B". I think the programmer has good reason to complain if his parentheses are not respected in this situation. In short, respecting parentheses has no bad effects, and not respecting them can be downright harmful. -- Dave Seaman ags@j.cc.purdue.edu
fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (09/15/88)
In article <3570@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >In short, any optimization possible for arrays of pointer to... is >also possible for conformant arrays. The reverse is _not_ true. 'taint so. Perhaps any *time* optimization, but certainly not any *space* optimization. I don't have to allocate space for unused array of pointer references. Consider sparse address spaces, such as sparse matrices. . . Marty +-+-+-+ I don't know who I am, why should you? +-+-+-+ | fouts@lemming.nas.nasa.gov | | ...!ames!orville!fouts | | Never attribute to malice what can be | +-+-+-+ explained by incompetence. +-+-+-+
jlg@lanl.gov (Jim Giles) (09/16/88)
From article <13567@mimsy.UUCP>, by chris@mimsy.UUCP (Chris Torek): > > You have just described C declarations. No, I didn't. I said that the declaration for an array should look (and mean) something different than the declaration of a pointer. In C, there are indeed two different syntaxes - they just both mean the _same_ thing. I can't declare an array in C without getting one or more pointers declared into the bargain. I want a language that gives _me_ the choice. C doesn't do it! Most of the pointer proposals for Fortran do! C _can't_ do it without making changes which aren't backward compatible. _All_ the Fortran pointer proposals I've seen _are_ backward compatible. (The Cray Fortran compiler has had pointers for years. Everything you can do with C pointers you can do with Fortran pointers. Arrays can be dynamically allocated - but the declaration and use of the arrays are identical with statically allocated arrays except for the additional POINTER statement. In C, the declaration of a dynamically allocated (multi-D) array is completely different from the declaration for a statically allocated one - the use is different too if you follow most implementation proposals.) J. Giles Los Alamos
jlg@lanl.gov (Jim Giles) (09/16/88)
From article <13570@mimsy.UUCP>, by chris@mimsy.UUCP (Chris Torek): > Sometimes (many people will break up ten-line expressions for the sake > of clarity). Nonetheless, there are two problems being solved: > overriding the default groupings, and specifying order of operation. > Any time you use a single solution for two (or more) orthogonal > problems, you have missed out on some potential orthogonality. This is true. But if you omit a functionality completely simply because you don't want to overload some part of the syntax - you haven't done the users any favors either. In fact, the parenthesis rule in Fortran is quite useful and is well understood by most programmers (because almost all languages except C have the same rule). Inserting parenthesis for clarity does indeed impeed optimization somewhat - but not as much as you might think. The only real case is when common sub-expressions are parenthesized differently so that they can't be folded together. The lack of grouping for precision control would pose a _much_ more serious problem. J. Giles Los Alamos
jlg@lanl.gov (Jim Giles) (09/16/88)
From article <1511@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): > (*twodarray)[10][5] = 'c'; > > Now you have. Gee, that looks like and array of pointers to me. If there's no pointers involved, what's that asterisk doing there? This is certainly _not_ an example of a 2-d array that is done without an array of pointers. J. Giles Los Alamos
shenkin@cubsun.BIO.COLUMBIA.EDU (Peter Shenkin) (09/16/88)
In article <3630@lanl.gov> jlg@lanl.gov (Jim Giles) writes: > ... I can't declare an array in C without getting >one or more pointers declared into the bargain. Sorry, but int a[10]; declares space for 10 ints and no pointers. If you want a pointer, too, you have to say, in addition, int *pa = &*a[0]; or some such. Of course, if you call a function with x = func( a ); what is passed to the function is the address of a[0], as in FORTRAN, but no extra storage has been declared. > ...(The Cray Fortran compiler has >had pointers for years. Everything you can do with C pointers you can >do with Fortran pointers. Arrays can be dynamically allocated.... A nice feature. And the common availability of this feature in many Fortrans is testimony to its usefulness. The fact that Fortran 8x, if it ever makes it, has a good chance of including it is further testimony. But standard (f77) Fortran doesn't have it, and most of us don't work on Crays, and many of us work on multiple machines. > ... In C, >the declaration of a dynamically allocated (multi-D) array is completely >different from the declaration for a statically allocated one... An unfortunate aspect of C. But at least we can do the allocation and use the array within the original definition of the C, assuming only the run-time library functions that are supplied with virtually all implementations of C that the numerical analyst, in any case, is likely to see. This is not true of Fortran. The proposed 8x standard indicates that those who find the feature useful wish to have it standardized; the mere fact that it is available one way or another in most good implementations is not enough for such users, despite the fact that, as Giles points out, some programmers use various preprocessors. At least C does provide a standard and source-code portable way of doing this, although I admit that C makes you stand on your head to create and use true (contiguous) dynamic multidimensional arrays whose shape (size and/or dimensionality) is not known until run-time. I agree with Giles that this is unfortunate. But I fail to see why he doesn't agree that the virtually universal availability of dynamic allocation in C, using the same syntactical convention, doesn't count in favor of C (over Fortran) in his eyes. -- ******************************************************************************* Peter S. Shenkin, Department of Chemistry, Barnard College, Columbia University New York, NY 10027 Tel: (212) 280-5517 (work); (212) 829-5363 (home) shenkin@cubsun.bio.columbia.edu shenkin%cubsun.bio.columbia.edu@cuvmb.BITNET
ok@quintus.uucp (Richard A. O'Keefe) (09/16/88)
In article <3974@h.cc.purdue.edu> ags@h.cc.purdue.edu.UUCP (Dave Seaman) writes: >In article <406@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: > [ explaining that a particular expression is not ambiguous in C ] >What are you afraid of? What problem does it cause if the compiler decides >to respect the extra parentheses that you put in for no reason? After all, >even in C under the K&R standard, there is no guarantee that the compiler >will NOT treat the expression differently because of the parentheses. Quite true. But if I stick extra parens into a C expression, whatever code the compiler comes up with, it was entitled to generate _anyway_. Because C has a lot more operator precedence levels than Fortran, and because it is not immediately obvious that, say, *a[i] means *(a[i]) -- hence the utility of the tool called "cparen" -- and because of macros, C programmers tend to write a lot of parentheses "just to be safe". For example, a Fortran programmer might write a statement function MIDPT(X, Y) = (X + Y)/2 but a C programmer would write #define MIDPT(X,Y) (((X) + (Y))/2.0) -- the parens around X and Y are needed in case their principal operators bind more weakly than "+", e.g. MIDPT(a < b, a < c) -- the parens around the whole are needed in case it is used within the scope of an operator binding more tightly than "/". Note that a compiler was formerly licenced to optimise MIDPT(a+b,c+d)/4.0 just like (a+b+c+d)/8.0, but is now required to do {({a+b} + {c+d})/2.0}/4.0. It is a bit worrying to suddenly be told that the parentheses you were putting in just to play safe now carry semantic import, just because people who were used to Fortran didn't like the idea of having an explicit "don't do this any other way" mark. >If all you are interested in is emphasizing grouping for the benefit of the >human reader, you can do that quite effectively by the proper use of white >space. You don't need parentheses. In fact, white space works BETTER than >parentheses for this purpose. Compare: > > t = a*cos(x) + b*cos(y) + c*f(x-y) + d*f(x+y) >with > t=((a*cos(x))+(b*cos(y)))+((c*f(x-y))+(d*f(x+y))) > >-- which would you rather read? No, in fact what I'm concerned about is the human *writer*. Since I read code with the aid of a text editor, I would rather have the second form: I can be *sure* of the grouping. With the white-space version, I *still* have to read every character unaided, because the spacing might be wrong. Consider t = a-cos(x) / b-cos(y) / c-f(x-y) / d-f(x+y) [example of why "strong" parens are useful] It is conceded that *some* way of saying "do this *exactly* as I wrote it" is a Good Idea. The point is that that is a _different_ thing to say from "I am confused about the operator precedence and want to make sure", and the two deserve different notation. Fortran having historically (ab)used parentheses for the strong form, I wouldn't dream of suggesting that that should be changed. C having historically used parentheses for purely syntactic effect, I think it is at best bad manners to change _that_; a new notation should have been used. +(...) seemed ok to me. I seriously doubt that many Fortran programmers Out There understand enough about numerical analysis to work out where strong brackets are needed. It would be a big help in reading Fortran programs (especially when trying to convert them to another language) if one only knew which parentheses were present for numerical reasons and which were not. Comments would be enough. Here are a couple of examples from "Numerical Recipes": WT = 1./(SIG(I) ** 2) Why has this been written like that instead of as WT = SIG(I) ** (-2) is there something deep I am missing here, or was it just a matter of taste? SXOSS = SX/SS ... SIGA = SQRT((1. + SX*SX/(SS*ST2))/SS) Is it really important that this should be computed as (SX*SX)/(SS*ST2) or perhaps SX/(SS*ST2)*SX rather than (SX/ST2)*SXOSS, or was it just what the authors thought clearest? {In context, I'd be more worried about overflow/underflow than about roundoff, so I'd have thought (SX/ST2)*SXOSS would be preferred on numeric grounds.} I hope these examples make my point clear: I do not regard *either* the Fortran or the pre-ANSI C positions on parentheses as satisfactory. There are *two* constructs, and both languages should have *both*. It is precisely because I _agree_ that control over evaluation is important that I want to know which parentheses are which!
chris@mimsy.UUCP (Chris Torek) (09/16/88)
>In article <13570@mimsy.UUCP> I wrote >>Any time you use a single solution for two (or more) orthogonal >>problems, you have missed out on some potential orthogonality. [and I add back the line:] Whether this orthogonality is in fact *useful* is another argument entirely. In article <3631@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >This is true. But if you omit a functionality completely simply because >you don't want to overload some part of the syntax - you haven't done >the users any favors either. In fact, the parenthesis rule in Fortran >is quite useful and is well understood by most programmers .... >The lack of grouping for precision control would pose a _much_ more >serious problem. I agree. Introducing temporary variables to force evaluation order (required in `old C') is significantly inelegant. This was a real problem with `old C'. I am just not sure I like the solution used in the dpANS (and in FORTRAN and all those other languages). Ah well, time will tell how well it works. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
peter@ficc.uu.net (Peter da Silva) (09/17/88)
In article <3645@lanl.gov>, jlg@lanl.gov (Jim Giles) writes: > From article <1511@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): > > (*twodarray)[10][5] = 'c'; > > Now you have. > Gee, that looks like and array of pointers to me. Nope, it's a pointer to an array. There's a difference. A big difference. > This is certainly _not_ > an example of a 2-d array that is done without an array of pointers. It certainly is. If you can't read that much 'C' correctly, then why are you even trying to carry on this debate? I refuse to carry on a battle of wits with an unarmed man. -- Peter da Silva `-_-' Ferranti International Controls Corporation. "Have you hugged U your wolf today?" peter@ficc.uu.net
PLS@cup.portal.com (09/17/88)
hjm@cernvax.UUCP (Hubert Matthews) writes >Consider the following cases: > > I = (5 / 4) * 5 (I gets 5) > > I = 5 / (4 * 5) (I gets 0) > > I = 5 / 4 * 5 (I gets 5 in F77, I gets something in C) Now just a minute. Surely you don't mean to say that the first two are both equivalent to the third except for a choice in order of operations? The second is a completely different formula. The two correct choices are I = (5 / 4) * 5 = 5 I = (5 * 5) / 4 = 6 I suspect there are very few compilers that do this kind of reordering. ++PLS onsider the following cases: I = (5 / 4) * 5 (I gets 5) I = 5 / (4 * 5) (I gets 0) I = 5 / 4 * 5 (I gets 5 in F77, I gets something in C) Personally, I wouldn't use case 3; I would always enforce an evaluation order by using parentheses. If this could be ambiguous in C, I wouldn't use it for numerical work. The same problem occurs when using mixed-mode arithmetic. Ev