I was going to comment on @Doug Currie that signed integer overflow was a tidbit too far fetched, although technically correct as answer. On the contrary!
On a second thought, I think Doug's answer is not only correct, but assuming a not entirely trivial three-liner as in the example (but a program with maybe a loop or such) should be extended to a clear, definite "yes". Here's why:
The compiler sees int i = 1, j = 2;
, so it knows that ++i will be equal to j
and thus cannot possibly be larger than j
or even ++j
. Modern optimizers see such trivial things.
Unless of course, one of them overflows. But the optimizer knows that this would be UB, and therefore assumes that, and optimizes according to, it will never happen.
So the ternary operator's condition is always-false (in this easy example certainly, but even if invoked repeatedly in a loop this would be the case!), and i
will only ever be incremented once, whereas j
will always be incremented twice. Thus not only is j
always larger than i
, it even gains at every iteration (until overflow happens, but this never happens per our assumption).
Thus, the optimizer is allowed to turn this into ++i; j += 2;
unconditionally, which surely isn't what one would expect.
The same applies for e.g. a loop with unknown values of i
and j
, such as user-supplied input. The optimizer might very well recognize that the sequence of operations only depends on the initial values of i
and j
. Thus, the sequence of increments followed by a conditional move can be optimized by duplicating the loop, once for each case, and switching between the two with a single if(i>j)
. And then, while we're at it, it might fold the loop of repeated increment-by-twos into something like (j-i)<<1
which it just adds. Or something.
Under the assumption that overflow never happens -- which is the assumption that the optimizer is allowed to make, and does make -- such a modification which may completely changes the entire sense and mode of operation of the program is perfectly fine.
Try and debug that.