That’s a mouthful of a title and it should telegraph that this post will be excruciatingly dull for anyone who isn’t interested in compiler theory, the parsing of computer languages, or the like.
Let’s get right to the code, shall we? Suppose you have these lines in PHP:
$a = 1;
$a = $a++;
echo $a."\n";
What do you suppose the output will be?
If you answered “2″, you’re probably thinking about the question correctly — but your answer is wrong.
If you answered “1″, you’re right — but unless you know the answer is 1 because you’ve actually tested it, or you’re a core PHP developer, you’ve most likely missed the subtlety of the question, as I did when I first heard it.
The question came up today on the php-general mailing list. Of course everyone, including me, lectured the OP for seven or eight replies about how PHP’s post-increment operator works, which completely missed the point.
The OP was perfectly familiar with that operator, which, in theory, affects its operand after the surrounding expression has been evaluated. So let’s look at that code again and consider what’s so odd about it:
$a = 1;
$a = $a++;
If the ++ operator works as expected, the assignment should first be evaluated. Then, $a should be incremented. But which $a gets incremented? And, come to think of it, what does “which $a” even mean? There’s only one variable named $a in the current scope.
So it would seem that, after the assignment, the one and only $a in the current scope should be incremented. Which would leave $a with a value of 2.
But if you test this out for yourself, you’ll find that $a actually ends up with a value of 1. In other words, PHP acts temporarily as if there were two variables named $a in the current scope. The one on the left side of the assignment persists; the one on the right gets incremented and then vanishes. (At least this is what happens in Ubuntu 9.04′s standard version of PHP. YMMV, but I suspect this isn’t the sort of behavior that changes very often in a language.)
Now try a similar thing in C:
int a = 1;
a = a++;
printf("%d\n", a);
Oops: The output is not 1, but 2! In other words, C does exactly what you would expect when you really think it through, while PHP does not. I found with some quick testing that Perl v5.10.0 and Groovy v1.6.3 both behave the same way PHP does.
Ultimately, does it matter? I mean, who in their right mind would write $a = $a++ anyway? It’s an interesting thought exercise for a certain kind of geek, though.