PHP: inexplicable behaviour of pre- and post-increment operators

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A week ago Dasn asked a question about converting arrays, and I quoted one possible way of
achieving his task, using the operation:

$i = 0; while ($i < $k) { $b[$a[$i++]] = $a[$i++];  }

I added the comment that "I have always been wary of using statements like this because I
was unsure when the incrementing would occur, so I tried it."

I received several CC e-mails replying to this post, including one rather critical comment
to the effect that pre-and post-increment were all quite simple, and I really ought to
learn the fundamentals before I started trying to do anything elaborate. 

I posted a reply to these e-mails, but as neither they, nor my reply, or any follow-up
discussion ever appeared in the discussion group I will repost this reply.  (I did have a
power failure at this time, so it is conceivable that any follow-up was lost as a result
of a glitch in my mailer, but I think it is more likely that there was a glitch in the
discussion group server.)

Unfortunately things aren't nearly as simple as this writer believes. The rule I have
always used is that if you use the same variable as an index on both sides of an assign
statement it is not safe to change the value of the index within the statement. While I
have achieved the result I wanted in the example above (using PHP 5.1.6 -- there is no
guarantee it would work with other implementations of PHP) the results of doing this in
the general case can be quite inexplicable.

The particular case which prompted my comment was the one where you want to copy part of
one array into the corresponding elements of another array.  In accordance with my rule, I
normally write:

$i = 0; $j=count($a); while ($i < $j) { $b[$i] = $a[$i]; ++$i; }

It is tempting to try to put the increment into the assignment statement. Clearly the
value of $a[$i] has to be read before it can be written to $b[$i], so the logical
expression would be:

while ($i < $j) { $b[$i++] = $a[$i]; } 	A.

However if you try this, you get $b[1] = $a[0], and so on. But if you try the alternative:

while ($i < $j) { $b[$i] = $a[$i++]; }		B.

You get $b[0] = $a[1], and so on (as you would expect). 

Out of curiosity, I then tried:

$i = -1; $j=count($a) - 1; while ($i < $j) { $b[$i] = $a[++$i]; }		C

This gave the desired result, and seemed moderately logical. However when I tried: 

$i = -1; $j=count($a) - 1; while ($i < $j) { $b[++$i] = $a[$i]; }		D

This gave exactly the same result.  It is quite impossible to explain the results in cases
A and D from the definitions of the pre-and post-increment operator, so I think I will
stick to my safe rule!

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux