You wrote "assume a C-like language". Just how C-like should it be?
First, it does appear that the author's logic is backwards:
It has the effect of assigning the value of a + 1 to a whenever
the evaluation of the left-hand component of the assignment precedes
the evaluation of the right-hand one.
In fact, it has that effect if the evaluation of the LHS follows the evaluation of the RHS.
Some "C-like" languages (in the sense that their syntax looks similar to C's) define the order of evaluation of expressions. (I think Java does this.) In such a language, the semantics of the code would depend on exactly how the language defines the order of evaluation. If the order is left-to-right, then the function call on the LHS (left-hand side) of the assignment will be evaluated first.
In C itself (and in C++), the order of evaluation is unspecified. The two function calls could be evaluated in either order, depending on the whim of the compiler (optimization can change this; so, in principle, can the phase of the moon). I don't believe the behavior of this particular code is actually undefined, which would mean that the language says nothing about how it behaves, but similar code such as:
a[i++] = a[i++] + 1;
does have undefined behavior, because
i is modified twice with no intervening sequence point. In C, the above could evaluate the LHS
i++ before the right one, or vice versa -- but those aren't the only possibilities. A C compiler is free to assume that your program doesn't modify
i twice between sequence points. This particular example seems easy for the compiler to detect, but in more complex cases it can be difficult or impossible to do so.
But the real answer to the question is: Don't write code like that.
You really don't need to have two function calls in a single statement, where the results depend on the order in which they're evaluated. Separate the calls into distinct statements, for example:
int x = f(3);
int y = f(3);
a[x] = a[y] + 1;
And in real life, you want better names than
a -- and
f() probably shouldn't return different results on successive calls, or it should be very clear why it needs to do so.
Write your code so that questions like this don't arise in the first place.