#32841 [Asn->WFx]: returned a member variable cannot be turned into reference
| From: | alan_k@php.net | Date: | Thu, 28 Apr 2005 08:59:49 +0000 |
| Subject: | #32841 [Asn->WFx]: returned a member variable cannot be turned into reference | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-78348@lists.php.net to get a copy of this message | ||
ID: 32841
Updated by: alan_k@php.net
Reported By: wagner at bonn dot edu
-Status: Assigned
+Status: Wont fix
Bug Type: Scripting Engine problem
Operating System: *
PHP Version: 4.3.11, 5.0.4
Assigned To: andi
New Comment:
What you are trying to do is feasable in different ways. - just not
the way you are trying.. (try the support channels for suggestions.)
- whether what you are trying to do is a good idea (maintance, code
readability, creating bugs....) is another question...
changing the engine behavior to do what you say is extremely complex.
And the return on fixing this would not be worth the instability that
it would involve (we know from previous efforts at looking at this).
hint: use
return &$this->var;
$tmp = &$foo->f_default();
incr($tmp);
Previous Comments:
------------------------------------------------------------------------
[2005-04-28 06:34:50] wagner at bonn dot edu
> In your case f_default() returns *copy*, not a reference
No it doesn't.
Try this as case 1 in the reproduce code as above:
--------------------------------------------------
case 1:
//forced reference works AND makes default behaviour
//work afterwards
echo incr($foo->f_ref())."\n";
echo incr($foo->f_default())."\n";
echo incr($foo->f_default())."\n";
break;
Expected result:
----------------
1
2
2
f_default() should return a copy
Actual result:
--------------
1
2
3
incr() gets a reference to $foo->v and modifies it
Since I filed this behaviour as another bug here
http://bugs.php.net/bug.php?id=32840
could it please be looked at too and be unbogusified?
------------------------------------------------------------------------
[2005-04-27 23:45:04] tony2001@php.net
Short version:
this is expected and the error message clearly says why:
only variables can be referenced and you cannot make a reference to an
expression result.
Long version:
In your case f_default() returns *copy*, not a reference as you wrongly
consider, while f_ref() returns reference and should work indeed.
But I'm a bit surprised to see that f_copy() works, as it should give
the same warning as with f_default().
Concerning the case 2, AFAIK it's because of some reference magic: when
you return $this->v as reference, it turns in refernce itself
(refcount++) and the following call to f_default() returns this
reference.
Though, it would be interesting to see what engine gurus say about it.
------------------------------------------------------------------------
[2005-04-26 14:54:41] wagner at bonn dot edu
Description:
------------
When returning a member-variable directly as a reference
parameter into a function, a fatal error occurs:
Fatal error: Only variables can be passed by reference ...
The reproduce code displays the bug (for $case=0) as well
as two simple workarounds that IMHO show that the
ZEND-Engine should be able to handle this with no need for
any error.
This seems to have been around for a while, at least PHP
4.3.x
Probably related to
http://bugs.php.net/bug.php?id=32840
Reproduce code:
---------------
$case = 0;
function incr(&$int) {
return $int++;
}
class foo {
var $v = 1;
function &f_ref() { return $this->v; }
function f_copy() { return (int)$this->v; } //forced copy through
type-cast
function f_default() { return $this->v; }
}
$foo =& new foo();
switch($case) {
case 0:
//default behaviour is broken
echo incr($foo->f_default())."\n";
case 1:
//forced reference works AND makes default behaviour work
afterwards
echo incr($foo->f_ref())."\n";
echo incr($foo->f_default())."\n";
break;
case 2:
//forced copy works
echo incr($foo->f_copy())."\n";
break;
}
Expected result:
----------------
incr() should get a copy of $foo->v
Actual result:
--------------
Fatal error: Only variables can be passed by reference in
foo.php on line 19
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=32841&edit=1