8

It's well-known that the order of evaluation of a function's arguments in unspecified and can differ between different compilers.

What doesn't seem so clear is whether function calls can be interleaved, in the following sense:

f(g(h()), i(j()))

Let's assume the compiler chooses to evaluate f's first parameter first. Is the compiler free to call j between calling h and g? I believe so, but I don't know where to find confirmation in the Standard.

James Hopkin
  • 13,099
  • 1
  • 38
  • 68
  • It also applies to plain C, or is the standard any different ? (that would be quite interesting) – Steve Schnepp May 07 '09 at 11:03
  • The C Standard says "The order of evaluation of the function designator, the arguments, and subexpressions within the arguments is unspecified, but there is a sequence point before the actual call.", so the effect seems to be the same. – James Hopkin May 07 '09 at 11:12
  • 2
    possible duplicate of [Compilers and argument order of evaluation in C++](http://stackoverflow.com/questions/621542/compilers-and-argument-order-of-evaluation-in-c) – Tim Cooper Jul 22 '12 at 20:38
  • See [this](http://stackoverflow.com/questions/621542/compilers-and-argument-order-of-evaluation-in-c). – Anton Gogolev May 07 '09 at 10:32

4 Answers4

13

The evaluation order is unspecified - see section 5.2.2/8 of the Standard:

The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered.

  • +1: I should read 5.2.2 again carefully - I'm sure the wording must cover the case I'm asking about – James Hopkin May 07 '09 at 10:45
  • Agreed, but perhaps you should edit your answer to say 'unspecified'. There's an important difference. – James Hopkin May 07 '09 at 10:52
  • +1: it contains the answer to your "Is the compiler free to call j between calling h and g?" question that is "Yes". – Steve Schnepp May 07 '09 at 11:01
  • I'm not so sure if you can derive that answer from the quote above. In general, while there is considerable lattitude to the order of evaluation of arguments, I do not think that you can do anything but call a function after you've finished evaluating its arguments. – MSalters May 07 '09 at 12:24
3

I don't know what the standard says, but I think that if it matters to you, then you should probably re-arrange the code so that you know what's going to happen in which order (temp variables are your friends). Even if you figure out what the standard says, AND if we assume that your compiler implements that correctly, you're still leaving a maintenance time bomb, because your successors WON'T know everything you do.

Michael Kohne
  • 11,516
  • 3
  • 43
  • 71
2

The evaluation order is not specified by the standart. It depends only on your compiler.

mrshpot
  • 276
  • 2
  • 10
  • In this case it depends on your compiler and potentially many other things. The freedom is given to allow optimizers to do the best job possible. As a result a compiler might produce a different order depending on the optimisation level. – Richard Corden May 07 '09 at 12:09
0

If the functions you're using in the same expression are somehow related (one affects the results of the other), so different order of calls give different results, then refrain of using nested functions in expressions.

I do it as good practice, exactly because, as the other said, the calling order is undefined (you could have even interlaced execution, if the optimizer thought it will be more optimal).

Cătălin Pitiș
  • 13,509
  • 2
  • 37
  • 61