Bug #29992 [Com]: foreach by reference corrupts the array

2012-02-09 Thread looris at gmail dot com
Edit report at https://bugs.php.net/bug.php?id=29992&edit=1

 ID: 29992
 Comment by: looris at gmail dot com
 Reported by:fletch at pobox dot com
 Summary:foreach by reference corrupts the array
 Status: Not a bug
 Type:   Bug
 Package:Scripting Engine problem
 Operating System:   linux
 PHP Version:5.0.1
 Block user comment: N
 Private report: N

 New Comment:

No one cares about the technical explanation about why this happens at a low 
level. I'm quite puzzled you are still in denial about this bug.


Previous Comments:

[2012-02-09 16:49:22] ras...@php.net

No matter how you paint this, it isn't a bug. What you are really asking for is 
some sort of block-level scoping. As such, it should be proposed as a feature 
request, but it would be a major change in the language. The simplest way to 
illustrate that is to just unroll the loops. Take this example:

$a = array(1,2);
foreach($a as &$b) { }
foreach($a as $b) { }
print_r($a);

The problem here is that people find it inconsistent that the 2nd loop changes 
$a. But if we unroll the loops and write the exactly equivalent code without 
the 
foreach construct we get:

$a = array(1,2);

// First loop, $b is a reference to each element in $a
$b = &$a[0];
$b = &$a[1];

// Second loop, $b is assigned the value of each element in $a
$b = $a[0];
$b = $a[1];

Those two pieces of code are identical in every way. The thing that confuses 
people is that $b is still a reference $a[1] going into the second loop.

Since PHP doesn't have block-level scoping, there is nothing in the language 
that would permit $b to be unset between the two loops without introducing a 
major inconsistency. In fact there is plenty of code that relies on this fact 
which would break if we made such an arbitrary change.

I suppose what you are asking for is syntax along the lines of:

$a = array(1,2);
{
  local $b = &$a[0];
  $b = &$a[1];
}
{
  local $b = $a[0];
  $b = $a[1];
}

Where $b is locally scoped in each of those blocks and it might look like this 
in a foreach case:

$a = array(1,2);

foreach($a as local &$b) { }
foreach($a as local $b) { }

Without such a scoping syntax change, something as simple as:

forach(array(1,2,3) as $b) { }
echo $b;

where the code fully expects $b to be 3 would break.


[2012-02-09 12:33:40] robbie at shapehq dot co dot uk

I feel very strongly that this behavior is wrong. It's not consistent with 
other languages and will cause great confusion!


[2011-10-20 04:56:50] bruce at kaskubar dot com

With all due respect to those who spend their time developing, debugging, and 
explaining PHP, BALDERDASH!

Elsewhere, those of us who continue to claim "bug" are supposed to be chastened 
by all the explanations that have been provided over the years. The fact that 
the reports persist and the explanations grow is evidence contrary to the 
finding of Bogus and in support of what is expected behavior.

Fletch's example, for example, is real and reproducible through at least v5.3.2.

How in the world can it be expected for a (second) loop and its object to 
perform as though no related instructions were executed previously, and then 
for that interaction to raise its ugly head for only the last iteration? It 
cannot be. It can be explained. But so can an earthquake be. That doesn't make 
it expected.

I am unaware of any other case where prior use of a variable affects subsequent 
use of the same-named variable where its value is being explicitly reset or, as 
in the case of foreach, implicitly reset by virtue of its purpose. (That is, we 
can use $i as a loop counter here and as a file handle there and as long as we 
don't cross their purposes in the space-time continuum, all is well.)

The only bogus thing about this bug report and all its cousins is their shared 
status.


[2011-09-02 15:13:42] publcishady at gmail dot com

If you describe how it works that's not an excuse for unexpected results. I 
understand why the last element becomes a reference, but I don't understand why 
it SHOULD become a reference. That's obviously a bug for me.


[2011-07-18 05:03:24] martijn at twotribes dot com

Well, it is expected by the people who designed the language perhaps, but not 
by me. Iterating through an array, without doing anything, shouldn't change the 
array. Period. If I do something similar in another language like C++, this 
will never be the result.




#49300 [NEW]: very bizarre loops with decimal numbers

2009-08-19 Thread looris at gmail dot com
From: looris at gmail dot com
Operating system: debian stable
PHP version:  5.2.10
PHP Bug Type: Unknown/Other Function
Bug description:  very bizarre loops with decimal numbers

Description:

Just look at the code.

Reproduce code:
---


Expected result:

0.1
0.2
0.3
0.4
0.5

0.1
0.2
0.3
0.4
0.5
0.6
0.7


Actual result:
--
0.1
0.2
0.3
0.4
0.5

0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8

-- 
Edit bug report at http://bugs.php.net/?id=49300&edit=1
-- 
Try a snapshot (PHP 5.2):
http://bugs.php.net/fix.php?id=49300&r=trysnapshot52
Try a snapshot (PHP 5.3):
http://bugs.php.net/fix.php?id=49300&r=trysnapshot53
Try a snapshot (PHP 6.0):
http://bugs.php.net/fix.php?id=49300&r=trysnapshot60
Fixed in SVN:
http://bugs.php.net/fix.php?id=49300&r=fixed
Fixed in SVN and need be documented: 
http://bugs.php.net/fix.php?id=49300&r=needdocs
Fixed in release:
http://bugs.php.net/fix.php?id=49300&r=alreadyfixed
Need backtrace:  
http://bugs.php.net/fix.php?id=49300&r=needtrace
Need Reproduce Script:   
http://bugs.php.net/fix.php?id=49300&r=needscript
Try newer version:   
http://bugs.php.net/fix.php?id=49300&r=oldversion
Not developer issue: 
http://bugs.php.net/fix.php?id=49300&r=support
Expected behavior:   
http://bugs.php.net/fix.php?id=49300&r=notwrong
Not enough info: 
http://bugs.php.net/fix.php?id=49300&r=notenoughinfo
Submitted twice: 
http://bugs.php.net/fix.php?id=49300&r=submittedtwice
register_globals:
http://bugs.php.net/fix.php?id=49300&r=globals
PHP 4 support discontinued:  http://bugs.php.net/fix.php?id=49300&r=php4
Daylight Savings:http://bugs.php.net/fix.php?id=49300&r=dst
IIS Stability:   
http://bugs.php.net/fix.php?id=49300&r=isapi
Install GNU Sed: 
http://bugs.php.net/fix.php?id=49300&r=gnused
Floating point limitations:  
http://bugs.php.net/fix.php?id=49300&r=float
No Zend Extensions:  
http://bugs.php.net/fix.php?id=49300&r=nozend
MySQL Configuration Error:   
http://bugs.php.net/fix.php?id=49300&r=mysqlcfg



#49300 [Bgs]: very bizarre loops with decimal numbers

2009-08-20 Thread looris at gmail dot com
 ID:   49300
 User updated by:  looris at gmail dot com
 Reported By:  looris at gmail dot com
 Status:   Bogus
 Bug Type: Unknown/Other Function
 Operating System: debian stable
 PHP Version:  5.2.10
 New Comment:

what are you talking about? string representation?

the second loop loops 8 times, when it should have looped only 7
times.

and using < or <= gives exactly the same result: it still loops for 0.8
when it shouldn't (since i wrote $value<0.8)

I assumed you would notice it but clearly you didn't, I'll be more
descriptive next time.

We do agree that if $value is 0.8, the expression $value<0.8 is FALSE,
now do we?


Previous Comments:


[2009-08-20 08:58:58] der...@php.net

Floating point values have a limited precision. Hence a value might 
not have the same string representation after any processing. That also
includes writing a floating point value in your script and directly 
printing it without any mathematical operations.

If you would like to know more about "floats" and what IEEE
754 is, read this:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
 
Thank you for your interest in PHP.

.

------------

[2009-08-19 20:39:01] looris at gmail dot com

Description:

Just look at the code.

Reproduce code:
---


Expected result:

0.1
0.2
0.3
0.4
0.5

0.1
0.2
0.3
0.4
0.5
0.6
0.7


Actual result:
--
0.1
0.2
0.3
0.4
0.5

0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8





-- 
Edit this bug report at http://bugs.php.net/?id=49300&edit=1



#49300 [Bgs]: very bizarre loops with decimal numbers

2009-08-20 Thread looris at gmail dot com
 ID:   49300
 User updated by:  looris at gmail dot com
 Reported By:  looris at gmail dot com
 Status:   Bogus
 Bug Type: Unknown/Other Function
 Operating System: debian stable
 PHP Version:  5.2.10
 New Comment:

unfortunatly, you do not understand how languages work.

a high level language, like php, must (MUST, not should!) abstract all
the low level mechamisms.
a developer who writes php code must not be required to know how things
work at levels below that of php.
if something unexpected like this happens, it's php's fault, not
programmer's!

every time someone finds a thing that is clearly a bug (clearly to any
sane person) and you state "it's working as intended", you only fool
yourself.
what's the point in programming in a high level language, if that
languages behaves in an unpredictable way, and its developers are happy
with it?
I don't care how php handles floating point numbers internally, it may
send all the data to a pair of monkey who do the math with pen and paper
and then send it back to the program for all I care (and that at least
would explain some oddities).

I perfectly know how floats are represented in computers, dude. I
perfectly know that it's a rounding issue caused by the conversion from
decimal to binary... I just don't care. While I code in php I expect the
language to be fool-proof, and I expect it to solve this problems
without me having to bother.
It can be done, just use a fractional representation for floats until
you are forced to switch to a normal one. I mean, I know you never will,
but it's still my duty to tell you what you should do.


Previous Comments:


[2009-08-20 12:18:41] scott...@php.net

Unfortunately you're not understanding how floating point maths is
represented with a computer. Read the link that derick pointed you to or
have a quick look at wikipedia.

----------------

[2009-08-20 10:36:22] looris at gmail dot com

what are you talking about? string representation?

the second loop loops 8 times, when it should have looped only 7
times.

and using < or <= gives exactly the same result: it still loops for 0.8
when it shouldn't (since i wrote $value<0.8)

I assumed you would notice it but clearly you didn't, I'll be more
descriptive next time.

We do agree that if $value is 0.8, the expression $value<0.8 is FALSE,
now do we?



[2009-08-20 08:58:58] der...@php.net

Floating point values have a limited precision. Hence a value might 
not have the same string representation after any processing. That also
includes writing a floating point value in your script and directly 
printing it without any mathematical operations.

If you would like to know more about "floats" and what IEEE
754 is, read this:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
 
Thank you for your interest in PHP.

.

----------------

[2009-08-19 20:39:01] looris at gmail dot com

Description:

Just look at the code.

Reproduce code:
---


Expected result:

0.1
0.2
0.3
0.4
0.5

0.1
0.2
0.3
0.4
0.5
0.6
0.7


Actual result:
--
0.1
0.2
0.3
0.4
0.5

0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8





-- 
Edit this bug report at http://bugs.php.net/?id=49300&edit=1



#49300 [Bgs]: very bizarre loops with decimal numbers

2009-08-21 Thread looris at gmail dot com
 ID:   49300
 User updated by:  looris at gmail dot com
 Reported By:  looris at gmail dot com
 Status:   Bogus
 Bug Type: Unknown/Other Function
 Operating System: debian stable
 PHP Version:  5.2.10
 New Comment:

actually, it's supposed to do just this kind of thing.

compared to C, it allows you not to declare variables, not to malloc
memory you want to use, not to destroy that memory, not to care about
converting variables from one type to another, not to care about types
at all.

it does a whole lot of things, all aimed at removing that burden from
the developer, so yes, it would be perfectly natural for it to store
floats in a much friendlier way when it's needed.


Previous Comments:


[2009-08-21 12:10:01] ras...@php.net

Just curious, have you filed this bug against every other high-level
language?  Because they all behave like this.  It is not PHP's job to
invent a better way to store floating point values.  



[2009-08-20 12:43:38] looris at gmail dot com

unfortunatly, you do not understand how languages work.

a high level language, like php, must (MUST, not should!) abstract all
the low level mechamisms.
a developer who writes php code must not be required to know how things
work at levels below that of php.
if something unexpected like this happens, it's php's fault, not
programmer's!

every time someone finds a thing that is clearly a bug (clearly to any
sane person) and you state "it's working as intended", you only fool
yourself.
what's the point in programming in a high level language, if that
languages behaves in an unpredictable way, and its developers are happy
with it?
I don't care how php handles floating point numbers internally, it may
send all the data to a pair of monkey who do the math with pen and paper
and then send it back to the program for all I care (and that at least
would explain some oddities).

I perfectly know how floats are represented in computers, dude. I
perfectly know that it's a rounding issue caused by the conversion from
decimal to binary... I just don't care. While I code in php I expect the
language to be fool-proof, and I expect it to solve this problems
without me having to bother.
It can be done, just use a fractional representation for floats until
you are forced to switch to a normal one. I mean, I know you never will,
but it's still my duty to tell you what you should do.



[2009-08-20 12:18:41] scott...@php.net

Unfortunately you're not understanding how floating point maths is
represented with a computer. Read the link that derick pointed you to or
have a quick look at wikipedia.

----------------

[2009-08-20 10:36:22] looris at gmail dot com

what are you talking about? string representation?

the second loop loops 8 times, when it should have looped only 7
times.

and using < or <= gives exactly the same result: it still loops for 0.8
when it shouldn't (since i wrote $value<0.8)

I assumed you would notice it but clearly you didn't, I'll be more
descriptive next time.

We do agree that if $value is 0.8, the expression $value<0.8 is FALSE,
now do we?



[2009-08-20 08:58:58] der...@php.net

Floating point values have a limited precision. Hence a value might 
not have the same string representation after any processing. That also
includes writing a floating point value in your script and directly 
printing it without any mathematical operations.

If you would like to know more about "floats" and what IEEE
754 is, read this:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
 
Thank you for your interest in PHP.

.



The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/49300

-- 
Edit this bug report at http://bugs.php.net/?id=49300&edit=1



Bug #29992 [Com]: foreach by reference corrupts the array

2010-05-24 Thread looris at gmail dot com
Edit report at http://bugs.php.net/bug.php?id=29992&edit=1

 ID:   29992
 Comment by:   looris at gmail dot com
 Reported by:  fletch at pobox dot com
 Summary:  foreach by reference corrupts the array
 Status:   Bogus
 Type: Bug
 Package:  Scripting Engine problem
 Operating System: linux
 PHP Version:  5.0.1

 New Comment:

This *IS* a bug, since no one would EVER expect this kind of behaviour.

And no one "might use this for some weird reason", believe me.



"foreach" means "do stuff FOR EACH element of an array".

It does not mean, to any sane person, "do stuff for each element of an
array except the last one, and twice for the one before the last one".



Your stubbornness in stating this is intentional is quite frightening.


Previous Comments:

[2006-08-07 14:18:11] kou...@php.net

Although there's a user note in the manual, still this problem is not
described in the documentation itself.



Anyway, I believe the behaviour of foreach in this case is extremely
dangerous. Imagine there's such a "referential" loop in a library which
is included by some other scripts and it operates on $_SESSION or some
other important array. Now any foreach in the other scripts might
corrupt the base array without even knowing it - just because the name
of the "value" variable is the same.



The main purpose of foreach itself is (as the name implies) to do
something "for each" element of the array, i.e. to provide an easier way
to traverse an array than the other loop constructs and not to touch
other variables or references that are still pointing somewhere, unless
it's done implicitly in the body of the loop.



IMHO, foreach has to clear the variables used for key-value pairs, i.e.
to unset the reference before proceeding, just like it resets the array
pointer. Otherwise we have to put a big red note in the manual to always
unset variables after using the referential syntax or to use
$long_descriptive_names_for_references, which is a little unreasonable
in the current context.


[2004-10-08 08:54:14] der...@php.net

Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

Right, thanks for that analysis. No bug here. (And no, we can't unset it
by default, as people might use this for some weird reason).


[2004-10-07 21:12:18] gardan at gmx dot de

There is no corruption. It is easy to explain this behaviour. Take the
following:



$arr = array(1 => array(1, 2), 2 => array(1, 2), 3 => array(1, 2));

foreach($arr as &$value) { }

foreach(array(1,2,3,4,5) as $key => $value) { }

echo $test[3];



After the first foreach() loop what you have in $value is a reference to
the last element in $arr (here: to array(1,2)).



Now, when the next foreach loop assigns a value to $value, it assigns
this value to where $value points, that is: to the last position of
$arr. Now in the second foreach() the last item of $arr becomes first 1,
then 2, etc and in the end, what you get as output by this program, is:



5



Not the expected:



Array



Now this is indeed very confusing if you don't know what's going on.



Solution:

unset $v before a new foreach() loop (maybe this could be done by php by
default?)


[2004-10-04 16:37:43] yaroukh at email dot cz

I believe the problem I'm gonna describe here has the same roots as the
one fletch has described ...

Try this:



slots =& $slots;

}



public function & getSlot($idx)

{

if(IsSet($this->slots[$idx]))

return $this->slots[$idx];



return null;

}



public function getLength()

{

return Count($this->slots);

}

}



// fill the array and create object {



$slots = Array(

'zero',

'one',

'two',

'three',

'four'

);



$aw = new ArrayWrapper($slots);



// }



// output A

var_dump($aw);



// iteration 1

for($idx = 0; $idx < $aw->getLength(); $idx++)

$aw->getSlot($idx);



// output B; everything is OK


[PHP-BUG] Bug #51412 [NEW]: inconsistency using uninitialized array elements

2010-03-27 Thread looris at gmail dot com
From: 
Operating system: linux, osx, (any?)
PHP version:  Irrelevant
Package:  Arrays related
Bug Type: Bug
Bug description:inconsistency using uninitialized array elements

Description:

While I agree that it would be better to actually initialize elements
before using them, it is anyway wrong that they behave in inconsistent ways
when you do that.



They should BOTH count as 0, hence become 1 and -1, OR they should **BOTH**
stay NULL.



It does not make any sense at all to have them behave in two different
ways.

Test script:
---
$pitale=array();

$pitale["ok"]++;

$pitale["bug"]--;

print_r($pitale);

Expected result:

Array

(

[ok] => 1

[bug] => -1

)



---OR---



Array

(

[ok] => 

[bug] => 

)



Actual result:
--
Array

(

[ok] => 1

[bug] => 

)

-- 
Edit bug report at http://bugs.php.net/bug.php?id=51412&edit=1
-- 
Try a snapshot (PHP 5.2):
http://bugs.php.net/fix.php?id=51412&r=trysnapshot52
Try a snapshot (PHP 5.3):
http://bugs.php.net/fix.php?id=51412&r=trysnapshot53
Try a snapshot (PHP 6.0):
http://bugs.php.net/fix.php?id=51412&r=trysnapshot60
Fixed in SVN:
http://bugs.php.net/fix.php?id=51412&r=fixed
Fixed in SVN and need be documented: 
http://bugs.php.net/fix.php?id=51412&r=needdocs
Fixed in release:
http://bugs.php.net/fix.php?id=51412&r=alreadyfixed
Need backtrace:  
http://bugs.php.net/fix.php?id=51412&r=needtrace
Need Reproduce Script:   
http://bugs.php.net/fix.php?id=51412&r=needscript
Try newer version:   
http://bugs.php.net/fix.php?id=51412&r=oldversion
Not developer issue: 
http://bugs.php.net/fix.php?id=51412&r=support
Expected behavior:   
http://bugs.php.net/fix.php?id=51412&r=notwrong
Not enough info: 
http://bugs.php.net/fix.php?id=51412&r=notenoughinfo
Submitted twice: 
http://bugs.php.net/fix.php?id=51412&r=submittedtwice
register_globals:
http://bugs.php.net/fix.php?id=51412&r=globals
PHP 4 support discontinued:  http://bugs.php.net/fix.php?id=51412&r=php4
Daylight Savings:http://bugs.php.net/fix.php?id=51412&r=dst
IIS Stability:   
http://bugs.php.net/fix.php?id=51412&r=isapi
Install GNU Sed: 
http://bugs.php.net/fix.php?id=51412&r=gnused
Floating point limitations:  
http://bugs.php.net/fix.php?id=51412&r=float
No Zend Extensions:  
http://bugs.php.net/fix.php?id=51412&r=nozend
MySQL Configuration Error:   
http://bugs.php.net/fix.php?id=51412&r=mysqlcfg