The input is a number (float x) and a (I assume) sorted list of numbers (float a[]) of size 'n'. It then proceeds to insert x on the first spot j where a[j-1] > x. To do this, it starts at the back (j = n) it copies all elements <= x to the next slot.
a[j--] = a[j-1] moves the element before a[j] into a[j], and then after the command is evaluated, it changes j to one element before where it is (decrements).
a[j--] = a[j-1]; may work or may not work, or may sometimes work and sometimes not work. The behaviour is undefined.
With its current implementation, the function insert() does not work. If it appears to have worked correctly during a particular run of the program, that was happenstance,
I think you're jumping the gun, Stewbond. Wouldn't that be the same as a[10] = a[10-1]? I thought post (in/de)crementing happened after the evaluation of the entire line.
I thought it would be a[10] = a[9] because the j-- would not get evaluated until after the assignment, since assignments always evaluate rhs before they start on lhs.
I guess you're right, Stew. Either way, I believe that it demonstrates the importance of what JLBorges and Disch were saying...it's better to just write clear code that's easily understandable, and let the compiler optimize it.
since assignments always evaluate rhs before they start on lhs.
This isn't true.
The compiler is free to evaluate any part of the expression in any order as long as it obeys operator precedence rules. In this case, all that means is that:
1) [j-1] is evaluated before the '='
2) [j--] is evaluated before the '='
There is nothing in operator precedence rules that says [j-1] must be evaluated before/after [j--] as they are kind of entirely different expressions.
Here's another example:
x = foo() + bar();
Which function is called first? foo or bar?
Again it's undefined. The only thing that's guaranteed is that:
1) foo() will be called before the + operator is evaluated
2) bar() will be called before the + operator
3) the + operator will be evaluated before the = operator