Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!yale!cmcl2!lanl!jlg From: jlg@lanl.gov (Jim Giles) Newsgroups: comp.lang.fortran Subject: Re: Function calls in the middle of subroutine CALLs? -- Is it standard fortran 77 ???? Message-ID: <57505@lanl.gov> Date: 19 Jul 90 16:57:01 GMT References: Organization: Los Alamos Natl Lab, Los Alamos, N.M. Lines: 45 In article <1990Jul19.014856.13421@maytag.waterloo.edu> dmurdoch@watstat.uwaterloo.ca (Duncan Murdoch) writes: > [...] > Does the standard specify in what order the arguments will be evaluated? > If they have side effects, it makes a big difference sometimes. I've been > bitten by a bug caused by the lack of such specification in Pascal. > [...] The Fortran standard allows functions to have side effects. But, it does _not_ allow such functions to be called in the same statement with other objects that might be effected by those side effects. For example: x = f(a) + g(x) Now, if g modifies x, the above statement is illegal. Similarly, if x is in common, f may modify x and also cause the statement to be illegal. Finally, f and g may share data through common which causes a difference in their evaluation - this would also be illegal. The rule is actually very simple: In a statement that contains more than one function reference, the value provided by each function reference must be independent of the order chosen by the processor for evaluation of the function references. [ANSI X3.9-1978, section 6.6.2] The standard also permits common expression elimination, ie. the evaluation of a common subexpression once with the result being used repeatedly. This led to such things as follows: x = f(a) + f(a) becomes x = 2 * f(a) This had some rather sad consequences for naive users trying to get two samples from a random number generator in the same expression. The way around this problem for random number generators was to use: x = rnd(0) + rnd(1) The optimizer didn't recognize the two calls as common expressions, so it didn't optimize them. The rnd() function was written to ignore its argument though - so the result here is the sum of two successive random variates. Note: you _still_ can't count on which _order_ the two calls are made in. J. Giles