Stang1 said:
The following statement:
line_buf[line_len++] = ' ';
is equivalent to:
line_buf[line_len] = ' ';
line_len++;
because post-increments are done AFTER the non-incremented values are
used in the statement.
Correct?
Nearly. In fact, it's correct enough for rock n' roll.
What follows probably seems a bit picky at present, but can matter when the
expressions get more complicated.
The order of evaluation is up to the implementation, provided that, at
certain points in the program (known as "sequence points"), everything
that should have been done by that point /has/ been done by that point.
So, for example, a compiler could legally translate:
line_buf[line_len++] = ' ';
by copying the value of line_len to *two* registers, say R1 and R2,
incrementing R1, storing R1 back into line_len, and then setting
line_buf[R2] equal to ' '.
Why would a compiler do this? Well, it may determine that it's the most
efficient way to do the operation on a particular architecture. Perhaps
the hardware can do the inc/store and the array update in parallel, or
something.
Your code is well-defined as written. The proper element of line_buf will
be updated, regardless of which of many correct translations is chosen.
But if the order in which subexpressions are evaluated matters to you,
break it down into several statements, with one evaluation per statement.
For example, if foo() and bar() each produced output as well as returning
a value, then if the order in which the outputs were produced is important
you should write: n = foo(); n += bar(); arr[n] = 6; rather than arr[foo()
+ bar()] = 6; because, in the latter, code, the compiler is free to call
foo() and bar() in either order.