Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!yale!cmcl2!lanl!lambda!jlg From: jlg@lambda.UUCP (Jim Giles) Newsgroups: comp.lang.misc Subject: Re: NOT Educating FORTRAN programmers to use C Message-ID: <14199@lambda.UUCP> Date: 19 Jan 90 23:26:30 GMT References: <12950@cbnewsc.ATT.COM> Lines: 84 From article <12950@cbnewsc.ATT.COM>, by res@cbnewsc.ATT.COM (Rich Strebendt): > [...] > It seems that this discussion has gotten to the "my optimizer is > bigger than your optimizer" stage. [...] Not at all. So far, the discussion has been restricted to things that could be optimized in one language and not in the other. Fortran permits optimization of procedure arguments that C must assume are aliased - no optimizer, no matter how sophisticated, can eliminate this difference. Fortran allows intrinsic functions to be optimized, C hasn't any intrinsics (I know, the new standard permits such - show me an available implementation before you mention it again). On the other hand, C can optimize procedure calls (or even 'inline' them) provided that the procedure and the call are in the same scope (file). I don't know of any C implementation that actually does this, but it _is_ permitted by the existing (de facto) language specification. (Note that Fortran 90 also allows this for internal procedures and for procedure calls within MODULES. Just like C and intrinsics, this is not a fair comparison until such time as implementations exist which actually perform the optimization.) > [... C is better because it ...] allows me to better describe my INTENT > to the compiler and let it generate code that needs LESS optimization. Actually, C is worse at this in some ways and only average in others. For example, When I wish to pass an array to a procedure, Fortran (and Pascal, Modula2, ADA, ...) lets me do so. In C, the procedure always sees a pointer instead of an array. Another example: when writing numerical programs you often need to force the order of evaluation of an expression to avoid over/underflow or to eliminate cancellation in subtractions. Fortran (pascal, Modula2, ADA, ...) lets me do so with parenthesis - C forces me to introduce temporary variables and _hope_ that the optimizer doesn't actually do a store/load. > [...] Similarly, > using the x += y construct instead of X=X+Y will be a winner for the > compiler (especially if x is a multidimensional array) and will > require no pattern matching abilities in the optimizer to detect -- This is a particularly bad example for you to use. The optimization that you want the compiler to do without is called "common subexpression elimination". It is important that your compiler know how to do this optimization even if you do have a '+=' operator. I wouldn't ever buy a compiler which didn't have this capability. A compiler without this capability is somewhat behind the state-of-the-art anyway (by about 30 years). Another reason this is a bad example is the nature of the operator itself. It is obviously very easy to implement. This kind of thing was known before C was invented. Certainly language designers have known about it in C for the last 15-18 years. YET: there has been no stampede among language designers to put these operators into their languages. Nor has there been a groundswell of user support (neither to the standards committees nor to the vendors) for these operators to be added to existing languages. In fact, aside from C users, there seems to be no interest in these operators at all. One last reason that this is a bad example is that these operators work on the expression level and not on the statement level. This is known (from several language design experiments) to be harmful to user's productivity. > [...] > (such as incrementing a pointer rather than incrementing an index for > an array then recomputing the address of the array element) [...] Once again, the optimization you refer to has a name: "strength reduction". Once again, I wouldn't _have_ a compiler which didn't do this. A compiler which fails to do this is, once again, slightly behind the times (with 30 years again being a fair estimate). In fact, the use of arrays (which are _NOT_ aliased to each other) is a direct win over using pointers (which must be _assumed_ aliased even when they're not). A further problem with this is that pointer incrementing on multi-dimensional arrays is particularly error prone. Unless your inner loop is the one which steps over the first/last (depending on language) index of the arrays, your stride for the pointer may not be one (1). If not (as is often the case in numerical programs), _you_ are responsible for using the correct strides, bounds, and corrections in each level of loop nesting. This is further aggravated if you are only computing something for a corner or region of the array. J. Giles