[PHP-DEV] Bug #6417 Updated: Incorrect behaviour with references and arrays

2001-12-12 Thread yohgaki

ID: 6417
Updated by: yohgaki
Reported By: [EMAIL PROTECTED]
Status: Analyzed
Bug Type: Scripting Engine problem
Operating System: Linux RedHat 6.2
PHP Version: 4.0.6-dev
New Comment:

I think PHP version (and OS) is better to be updated. It's hard to know which version 
is the last PHP version tested.

Previous Comments:


[2001-11-22 18:24:27] [EMAIL PROTECTED]

I would like to see this fixed, it's a serious bug IMO.
Hope this serves as a reminder to someone (:





[2001-05-23 18:49:42] [EMAIL PROTECTED]

Resurfacing.

Is there any work being done on this? Or should I put this in the docs? 

If you don't expect it, this bug can create very strange behaviour, for example when 
you have some library function that creates references, it can mix up your script.

This is definitely a bug, and should be fixed a.s.a.p.
The fix is included here!

status - analyzed (imo it is even critical, this is straight against the principle of 
assigning by value:

[documentation]
In PHP, variables are always assigned by value. That is to
say, when you assign an expression to a variable, the
entire value of the original expression is copied into the
destination variable. This means, for instance, that after
assigning one variable's value to another, changing one of
those variables will have no effect on the other.

)



[2001-04-28 15:27:01] [EMAIL PROTECTED]

Reproduced in latest verison



[2000-08-31 08:54:19] [EMAIL PROTECTED]

Confirmed for 4.0.2.



[2000-08-29 12:17:34] [EMAIL PROTECTED]

?php
/*
I've discovered some slightly counter-intuitive behaviour
with references and arrays. I'm not sure whether this is
actually a bug or a 'feature', but if it is the latter then
it should be documented as such.

Consider the following code involving references and integers:
 */

$a = 5;
$b = $a;
$c = $a;
$c = 10;

echo (1) a: $a (should be 5)br\n;

/*
Here we have created a variable ($a), made a reference to it ($b),
made a copy of the original variable ($c), changed the copy ($c=10),
and then printed out the original value.

This is all fine and as expected.

Now let's try the same thing, but with the addition of arrays:
 */

$A = array();
$A[0] = 5;
$b = $A[0];
$C = $A;
$C[0] = 10;

echo (2) A[0]: $A[0] (I expected it to be 5)br\n;

/*
Thus, having copied the array $A to $C, we have actually made
$C[0] *another* reference to the $A[0] (which is also referenced
by $c). I would have expected $C[0] to have become detached from
the reference (as in $c = $a in the first example).

Taking out the line '$b = $A[0]' in the example above yields the
expected behaviour:
 */

$A = array();
$A[0] = 5;
$C = $A;
$C[0] = 10;

echo (3) A[0]: $A[0] (expected it to actually be 5 this time)br\n;

/*
Q: What's the explanation for all of this?

A: When the Zend Engine constructs a copy of an array/hash, it constructs
copies of the individual elements by using zval_add_ref (zend_variables.c).
This simply increases the reference count of the value in question. If
that value happens to be referenced by more than one name, it has
the 'is_ref' flag set. However, in the case of copying array elements,
the values are still _not_ separated if they have 'is_ref' set.

As I mentioned above, I'm not sure whether this is actually the desired
behaviour or not. In either case, I couldn't find it documented clearly
anywhere (maybe I didn't look hard enough--if not, sorry in advance!).

Working under the assumption that the behaviour is incorrect (I 
certainly find it very confusing), I worked out the following fix to
the issue (assuming my understanding of the Zend Engine is correct):

Instead of using zval_add_ref as the constructor when copying arrays,
use this:

ZEND_API void zval_add_ref_or_separate(zval **p)
{
if (PZVAL_IS_REF(*p))
{
SEPARATE_ZVAL(p);
} else {
zval_add_ref(p);
}
}

Another question is whether there are similar issues with objects? I 
haven't investigated...

Note: I haven't included PHP modules/php.ini etc since I'm
fairly 

[PHP-DEV] Bug #6417 Updated: Incorrect behaviour with references and arrays

2001-11-22 Thread venaas

ID: 6417
Updated by: venaas
Reported By: [EMAIL PROTECTED]
Status: Analyzed
Bug Type: Scripting Engine problem
Operating System: Linux RedHat 6.2
PHP Version: 4.0.6-dev
New Comment:

I would like to see this fixed, it's a serious bug IMO.
Hope this serves as a reminder to someone (:



Previous Comments:


[2001-05-23 18:49:42] [EMAIL PROTECTED]

Resurfacing.

Is there any work being done on this? Or should I put this in the docs? 

If you don't expect it, this bug can create very strange behaviour, for example when 
you have some library function that creates references, it can mix up your script.

This is definitely a bug, and should be fixed a.s.a.p.
The fix is included here!

status - analyzed (imo it is even critical, this is straight against the principle of 
assigning by value:

[documentation]
In PHP, variables are always assigned by value. That is to
say, when you assign an expression to a variable, the
entire value of the original expression is copied into the
destination variable. This means, for instance, that after
assigning one variable's value to another, changing one of
those variables will have no effect on the other.

)



[2001-04-28 15:27:01] [EMAIL PROTECTED]

Reproduced in latest verison



[2000-08-31 08:54:19] [EMAIL PROTECTED]

Confirmed for 4.0.2.



[2000-08-29 12:17:34] [EMAIL PROTECTED]

?php
/*
I've discovered some slightly counter-intuitive behaviour
with references and arrays. I'm not sure whether this is
actually a bug or a 'feature', but if it is the latter then
it should be documented as such.

Consider the following code involving references and integers:
 */

$a = 5;
$b = $a;
$c = $a;
$c = 10;

echo (1) a: $a (should be 5)br\n;

/*
Here we have created a variable ($a), made a reference to it ($b),
made a copy of the original variable ($c), changed the copy ($c=10),
and then printed out the original value.

This is all fine and as expected.

Now let's try the same thing, but with the addition of arrays:
 */

$A = array();
$A[0] = 5;
$b = $A[0];
$C = $A;
$C[0] = 10;

echo (2) A[0]: $A[0] (I expected it to be 5)br\n;

/*
Thus, having copied the array $A to $C, we have actually made
$C[0] *another* reference to the $A[0] (which is also referenced
by $c). I would have expected $C[0] to have become detached from
the reference (as in $c = $a in the first example).

Taking out the line '$b = $A[0]' in the example above yields the
expected behaviour:
 */

$A = array();
$A[0] = 5;
$C = $A;
$C[0] = 10;

echo (3) A[0]: $A[0] (expected it to actually be 5 this time)br\n;

/*
Q: What's the explanation for all of this?

A: When the Zend Engine constructs a copy of an array/hash, it constructs
copies of the individual elements by using zval_add_ref (zend_variables.c).
This simply increases the reference count of the value in question. If
that value happens to be referenced by more than one name, it has
the 'is_ref' flag set. However, in the case of copying array elements,
the values are still _not_ separated if they have 'is_ref' set.

As I mentioned above, I'm not sure whether this is actually the desired
behaviour or not. In either case, I couldn't find it documented clearly
anywhere (maybe I didn't look hard enough--if not, sorry in advance!).

Working under the assumption that the behaviour is incorrect (I 
certainly find it very confusing), I worked out the following fix to
the issue (assuming my understanding of the Zend Engine is correct):

Instead of using zval_add_ref as the constructor when copying arrays,
use this:

ZEND_API void zval_add_ref_or_separate(zval **p)
{
if (PZVAL_IS_REF(*p))
{
SEPARATE_ZVAL(p);
} else {
zval_add_ref(p);
}
}

Another question is whether there are similar issues with objects? I 
haven't investigated...

Note: I haven't included PHP modules/php.ini etc since I'm
fairly sure
this issue is unrelated to any site-specific setup.
 */ 
?






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


-- 
PHP