DISCLAIMER: This is not a real-world example. It is just a theoretical question of how these languages work.
What exactly are the differences between C/C++, C#, and Java when it comes to post & pre increment operators?
This is what I get with VC++10, Java 1.6, and C# 4
int a = 2;
int b = a++ + a++;
int c = ++a + a++ + a++;
+-----+------+------+----+
| C | C++ | Java | C# |
+-----+-----+------+------+----+
| a | 7 | 7 | 7 | 7 |
+-----+-----+------+------+----+
| b | 4 | 4 | 5 | 5 |
+-----+-----+------+------+----+
| c | 15 | 15 | 16 | 16 |
+-----+-----+------+------+----+
Java and C# evaluate expressions from left to right, and the side-effects are visible immediately.
In C++, the order of evaluation of subexpressions is unspecified, and modifying the same object twice without an intervening sequence point is undefined behavior.
I don't have the time to write up a detailed description of the differences between C++, C, C# and Java. I will merely say that the C# behaviour of the pre and post increment operators is fully specified (in single-threaded scenarios; if you want to know about its atomicity, guarantees about observations of read and write orders in multi-processor weak memory models and so on, you're on your own to do that research.) It is not fully specified in C and C++; a compiler has broad lattitude to do whatever it pleases with re-ordering side effects. I have never used Java so I'm not going to hazard a guess as to what Java does.
For more information on what C# does you should read the C# specification. For a short take on it, read my answer to this question:
What is the difference between i++ and ++i?
For an even shorter take:
Subexpressions in a C# expression are logically grouped by precedence and associativity, and then evaluated from left to right regardless. (So for example, A() + B() * C() evaluates A(), then B(), then C(). The fact that the multiplication "comes before" the addition is irrelevant; the subexpressions are always evaluated left to right.)
If the evaluation of a subexpression causes a side effect because of a pre or post increment subexpression then the side effect happens immediately before the result is produced.
In C++, this is undefined behaviour, so any answer would be correct. See Undefined behavior and sequence points for further details.
Not sure about other languages, but I would expect this code to be incorrect there, too.
EDIT:
See Eric Lippert's answer about C#. He disproves my assumption about C#'s behaviour.
In C++ at least this undefined behaviour. Quoting the C++ standard:
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.
The Java memory model ensures the order the loads and stores are done, so it should come out the same on any JVM (I believe).
It looks like C++ has the same order of operations, but once you use it twice on a line you start running into other stuff (Vlad is right there). If you try other C++ compilers, you may find they come up with different answers.
I'm sure C# has the same order of operations, but my guess is they have a memory model (like Java) that ensures consistency, but I don't have a lot of knowledge here.
I like this question and found very good explanations but I just want to explain this question by it's value how it is evaluated:
I will only talk about java and c/C++ as I have no knoledge about C#
Statements are evaluated in following ways
In java
Statement ||||||||||||||||||||||||||||||||||||||||||||||||||||||| Trace
int a= 2; a=2
int b= a++ + a++; a=2, a=3
here value of a=4
int c = ++a + a++ + a++; a=5, a=5, a=6
here value of a=7
In C/C++
Statement Trace
int a= 2; a=2
int b= a++ + a++; a=2, a=2
here value of a=4
int c = ++a + a++ + a++; a=5, a=5, a=5
here value of a=7
In short in java expression goes left to right so at the 2nd "a" it will fetch new value and in c/c++ it will first evaluate whole expression and then increment all operands of statement.
精彩评论