Officially
this type of code (that which modifies an Lvalue multiple times
within the same sequence interval) invokes "undefined behaviour", which
means that the compiler can do "anything" - although highly unlikely, the
compiler can happily return 6 6 6 in this case, and leave the value of i
at 31415 (or anything else) ... and be performing in a perfectly legal sense
- undefined operation is exactly that. The function performed is not
defined by the standard.
I think the functions to be performed are defined, and only their order is
undefined.
Thats is the expected result, however since we are performing multiple modifications
to an Lvalue within one sequence interval, the behaviour is "undefined"
according to
the C standard - this means that "anything goes", and there is no guarantee that
it
will be the expected result, or even one of several expected results (although this
will be almost always the case).
Although highly unlikely that the compiler writer would go to lengths to detect
this happening and produce non-intuitive results, other factors in the compilation
process might cause results you didn't expect - for example, a compiler may defer the
increments until the next sequence point, and just do a single addition of 3 - a simple
optimization, allowed by the definition of the language, but it would cause the three
intermediate results to be 0 0 0 - not what you expected (as described above), yet
perfectly reasonable to a compiler writer.
This is perfectly legal in this case because the effect of the '++' is a side
effect, and does not have to be applied until the next sequence point.
On other
words, it's not valid 'C' (although it is syntactically correct,
and most compilers will accept it without a diagnostic).
Which would make this an overstatement. I think it is perfectly valid C,
and the compiler has (after much deliberation) been allowed to generate the
most efficient code.
It is not a valid conforming C program (or fragment thereof). Any C program
which relies on undefined behaviour is non-conforming. This does not mean that
it doesn't work, or even that it does not happen to do what you expect - it
does mean that it is not guaranteed by the C standard to do what you expect
(or any particular thing).
Sometimes a compiler may choose one particular approach over another for the
sake of efficency, however often the exact ordering of operations performed
within sequence points have more to do with details of the compiler architecture
and not necessarily in a given case to do with efficiency.
I think the
OP's point has been completely missed (that a valid program is
a inherently very definitive and detailed specification).
I thought the point was that, at the margins, the "valid program" is *not*
as detailed a specification as was claimed/expected. (Though I still don't
know of anything more detailed. In fact, I think most programs are
over-specifications of the desired behavior. That is, they require a lot of
specific behavior that is actually unimportant to the correct result.)
IIRC the original posters point was as I stated (more or less), and it was in
a followup that someone contrived an example of how to use undefined behaviour
to make a specific program which was non-deterministic (at least between various
compilers).
In any case, it doesn't matter - there is no reason to invoke undefined behaviour
in your program. If you wish to print the value of i, i+1 and i+2 and leave i
advance by three, use: printf("%d %d %d", i, i+1, i+2); i += 3;
Your program will now be deterministic across all conforming implementations.
Now, tell me what will be printed:
int i = 0;
i = i++;
printf("%d\n", i);
Regards,
Dave
--
dave04a (at) Dave Dunfield
dunfield (dot) Firmware development services & tools:
www.dunfield.com
com Collector of vintage computing equipment:
http://www.parse.com/~ddunfield/museum/index.html