@smbell said:
@Angstrom said:@shadowman said:Yup. At least in c++, that's correct.
#include <iostream>
int main() {
int a = 42;
a = a++; // whups
std::cout << a << std::endl;
return 0;
}
This displays 42.
...on your machine, compiler, and configuration. The statement marked "whups" has, formally, undefined behaviour. The program could print 42, 43, 41, format your hard drive, mail nasty pictures of yourself and a goat to your boss, or make demons fly out your nose and still fall within the C++ specification.
In C/C++ (I'm pretty sure both) this has undefined behaviour, but in Java it's behaviour is specifically ordered. Basically the unary increment operator has a higher precedent than the assignment operator. I've seen it work both ways with various C++ compilers (although I can't remember it ever mailing those pictures to my boss, guess I've been lucky).
You are confusing operator precedence (not "precedent") with evaluation order. Operator precedence indicates how "tightly" an operator binds to operands. People unfamiliar with Lisp get a swift kick in the face when they first try it, because Lisp has NO precedence rules, and parentheses are required for all ambiguous expressions.
For example, the following statement is actually ambiguous:
i = j++;
It could be interpreted as:
(i = (j++));
or
(i=j)++; // which would be equivalent to i=j; i++;
Now, in the case of certain screwy constructs, like this:
a = a++;
a = (a+=5);
printf("a is %d, a++ is %d\n", a, a++); // this might not output a true statement!
C/C++ says the results of these operations are undefined, because the order that the pieces are evaluated in is not guaranteed. In fact, most compilers will actually evaluate the a++ first to produce more efficient code (because the arguments are evaluated and placed onto the stack in reverse order).
The only guarantee you have is that, for example:
if (a || b) { ... }
Here, 'a' is always evaluated first, and only if it is false is 'b' evaluated. This is so that you can do this sort of thing:
int *ptr;
if (ptr==NULL || *ptr == 0) { ptr_is_null_or_zero(); }
without worrying that the compiler might try to check *ptr first, and crash if it's NULL. Visual Basic doesn't have this feature, leading the (already verbose) VB code to require constructs like:
dim flag as boolean
flag = (obj is nothing)
if not flag then flag = (obj.member = 5) ' note the evil dual meaning of =
if flag then
' whee
end if
(VB.NET adds AndAlso and OrElse with short-circuit evaluation, but it's still ugly as sin.)
Anyway, Java *does* have a very specific evaluation order specification. Details here:
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html
Although I must admit, based on the documentation there, it looks like 'x = x++' in Java *should* leave 'x' unincremented.