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

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

am 27.02.2010 05:01:37 von Clancy

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

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

am 01.03.2010 12:17:14 von Martin Zvarik

Mess


Dne 27.2.2010 5:01, clancy_1@cybec.com.au napsal(a):
> 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

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

am 03.03.2010 06:34:08 von Adam Richardson

--00504502d295eacfc00480ded454
Content-Type: text/plain; charset=ISO-8859-1

Thanks for taking time to provide the examples, Clancy, I'll know what
potential pitfalls to wary of now :)

On Fri, Feb 26, 2010 at 11:01 PM, wrote:

> 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
>
>


--
Nephtali: PHP web framework that functions beautifully
http://nephtaliproject.com

--00504502d295eacfc00480ded454--

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

am 03.03.2010 15:21:06 von haliphax

--0016e6db2b0a60e30e0480e63125
Content-Type: text/plain; charset=UTF-8

> On Fri, Feb 26, 2010 at 11:01 PM, wrote:
> > while ($i < $j) { $b[$i] = $a[$i++]; } B.
> >
> > You get $b[0] = $a[1], and so on (as you would expect).
>

Wouldn't that be $b[0] = $a[0], with the value of $i being 1 *after* the
statement was finished executing? You used a post-decrement operator on $i
at the end of your statement, so I don't think that $i would be increased
before being used to index into the $a array.


// Todd

--0016e6db2b0a60e30e0480e63125--

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

am 04.03.2010 00:46:12 von Clancy

On Wed, 3 Mar 2010 08:21:06 -0600, haliphax@gmail.com (haliphax) wrote:

>> On Fri, Feb 26, 2010 at 11:01 PM, wrote:
>> > while ($i < $j) { $b[$i] = $a[$i++]; } B.
>> >
>> > You get $b[0] = $a[1], and so on (as you would expect).
>>
>
>Wouldn't that be $b[0] = $a[0], with the value of $i being 1 *after* the
>statement was finished executing? You used a post-decrement operator on $i
>at the end of your statement, so I don't think that $i would be increased
>before being used to index into the $a array.

Try it!

Clancy

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