Arithmetic - Order of Evaluation of Functional Parameters

Chapter chap3 section 10

A final important point in this chapter is to consider the output produced by the following program

main()
{
	int	x=5;
	printf("Values are %d and %d\n",x++,++x);
}

Before revealing the results let's see if we can work out what the output of the program will be. You might typically argue along the following lines.

We need to consider the values passed to the printf() function. The first of these is the value of the expression "x++". This is the use-and-increment (prefix) flavour of "++" so the value of the expression is 5 and as a side effect of evaluating the expression the value of x is increased to 6. The value of the expression "++x" is now calculated, this is the "increment-and-use" flavour of "++" so the value of the expression is clearly 7. Thus the expected output is

Values are 5 and 7
and compiling and running the program on the SUN Sparc Station produced exactly the expected output. What problem could there possibly be with this simple program ? Trying the same program using the Turbo C compiler resulted in the output
Values are 6 and 6
This is rather surprising but what has happened is actually quite easy to understand, if rather inconvenient. The C programming language standard rules quite specifically allow the parameters to be passed to a function to be evaluated in any convenient order. The SUN Sparc station compiler worked left to right, which seems more natural, whereas the Turbo C Compiler worked right to left which may be more efficient in some circumstances.

This must be remembered when writing programs that are to be compiled on many different machines. Some compilers provide flags or options to allow the user to control the order of functional parameter evaluation.

A similar difficulty arises when considering the output of a program such as

main()
{
	int	x = 4;
	printf("Result = %d\n",x++ + x);
}
Since the standard allows expressions involving commutative associative operators such as "+" to be evaluated in any order a moment's thought shows that the value printed out would be 8 for right-to-left evaluation and 9 for left-to-right evaluation. On the SPARC system the output was
Result = 8
whereas the Turbo C compiler gave the result
Result = 9
Strictly the behaviour of the program is undefined, which means that anything might happen.


Exercises