Pass by reference (5.1.1 vs 5.1.2)

php.internals

Rishad Omar

20 years ago
Hello, I've upgraded from 5.1.1 to 5.1.2 and discovered the following unexpected difference. Best shown by example. <? function getArray(&$arr) { $arr[] = 12; } getArray($p = array()); print_r($p); ?> In php 5.1.1, the $p is passed correctly as reference and so returns with the value 12 in its first element. I regard this as correct behaviour. In php 5.1.2, the $p is passed by value. So on return, $p is still empty! This can be fixed as follows: $p = array(); getArray($p); The following example works, as expected, in both 5.1.1 and 5.1.2. <? class A { public $i = 9; } function doAmend(A &$a) // & not required because class instance passed by reference by default { $a->i += 30; } doAmend($b = new A); print_r($b); // this prints the value of member i as 39 as expected. ?>

Matt Sicker

20 years ago
On Monday 24 July 2006 10:52, Rishad Omar wrote:
> Hello, > > I've upgraded from 5.1.1 to 5.1.2 and discovered the following > unexpected difference. Best shown by example. > > <? > function getArray(&$arr) > { > $arr[] = 12; > } > > getArray($p = array()); > print_r($p); > ?> > > In php 5.1.1, the $p is passed correctly as reference and so returns > with the value 12 in its first element. I regard this as correct > behaviour. In php 5.1.2, the $p is passed by value. So on return, $p > is still empty! This can be fixed as follows: > $p = array(); > getArray($p); > > > > The following example works, as expected, in both 5.1.1 and 5.1.2. > > <? > class A > { > public $i = 9; > } > > > function doAmend(A &$a) // & not required because class instance > passed by reference by default > { > $a->i += 30; > } > > doAmend($b = new A); > print_r($b); // this prints the value of member i as 39 > as expected. > > ?>
I'm guessing it has something to do with a memory leak. Either that, or scope; creating a variable inside of a function call probably goes out of scope after the function returns. Enable error_reporting(E_ALL| E_STRICT) and see what happens.
-- Matt Sicker

Johannes Schlueter

20 years ago
Hi, On Monday 24 July 2006 17:52, Rishad Omar wrote:
> getArray($p = array());
Here you are relying on undefined behavior. It is not defined wether $p = array() or the function call getarray($p) should be executed first so the order might always change. You should always use the two lines $p = array(); getArray($p); to be safe. johannes

Todd Ruth

20 years ago
It looks like http://www.php.net/manual/en/language.operators.assignment.php could use a bit of updating. A paragraph about php 5 or a link to the semantics changes for php 5 would help newbies. The text about php4 says there is copy on assignment, which implies a performance hit for using = instead of =&, but I believe "copy on change" is more accurate. It wouldn't hurt to explicitly say that "=" is generally better than "=&" (unless you really need an alias). A user comment has been there unchallenged for over 2 years saying you can pass an assignment as a reference to a function, so it isn't surprising that someone considered the 5.1.1 to 5.1.2 change an issue. (Not that a user comment should bind the php devs, but when the comment goes unchallenged, it can lead to false impressions.) Perhaps some text explaining the assignment returns an r-value would be helpful. (If people understand "($x = 1) = 2;" shouldn't work, they might understand that passing "$x=1" to a function by reference shouldn't affect $x. (or should "($x = 1) = 2;" work and 5.1.2 had a real bug?)) I have to say the documentation for php is completely awesome and is a major factor in our company using the language. I just point out the above to help; it isn't a complaint. BTW, I disagree with the post below that indicates the issue is the order of calling. There is no way to call a function before doing the work in the argument list. If I call f(1+2), I can be sure the computation to get 3 will be performed _before_ calling f. The issue with f($p=array()) is that "$p=array()" is an r-value. - Todd On Mon, 2006-07-24 at 19:16 +0200, Johannes Schlueter wrote:
> Hi, > > On Monday 24 July 2006 17:52, Rishad Omar wrote: > > getArray($p = array()); > > Here you are relying on undefined behavior. It is not defined wether $p = > array() or the function call getarray($p) should be executed first so the > order might always change. > > You should always use the two lines > $p = array(); > getArray($p); > to be safe. > > johannes >
-- Todd Ruth <truth@proposaltech.com>

Ron Korving

20 years ago
Actually Todd, ...
> There is no way to call a function > before doing the work in the argument list. If I call f(1+2), > I can be sure the computation to get 3 will be performed > _before_ calling f. The issue with f($p=array()) is that > "$p=array()" is an r-value.
...that is theoretically very possible, and it's something called "lazy evaluation": http://en.wikipedia.org/wiki/Lazy_evaluation - Ron "Todd Ruth" <truth@proposaltech.com> wrote in message news:1153763607.30382.184.camel@notebook.local...
> It looks like > http://www.php.net/manual/en/language.operators.assignment.php > could use a bit of updating. A paragraph about php 5 or a > link to the semantics changes for php 5 would help newbies. > The text about php4 says there is copy on assignment, which > implies a performance hit for using = instead of =&, but I > believe "copy on change" is more accurate. It wouldn't hurt > to explicitly say that "=" is generally better than "=&" > (unless you really need an alias). A user comment has been > there unchallenged for over 2 years saying you can pass an > assignment as a reference to a function, so it isn't surprising > that someone considered the 5.1.1 to 5.1.2 change an issue. > (Not that a user comment should bind the php devs, but when > the comment goes unchallenged, it can lead to false impressions.) > Perhaps some text explaining the assignment returns an r-value > would be helpful. (If people understand "($x = 1) = 2;" > shouldn't work, they might understand that passing "$x=1" to > a function by reference shouldn't affect $x. (or should > "($x = 1) = 2;" work and 5.1.2 had a real bug?)) > > I have to say the documentation for php is completely awesome > and is a major factor in our company using the language. I > just point out the above to help; it isn't a complaint. > > BTW, I disagree with the post below that indicates the issue is > the order of calling. There is no way to call a function > before doing the work in the argument list. If I call f(1+2), > I can be sure the computation to get 3 will be performed > _before_ calling f. The issue with f($p=array()) is that > "$p=array()" is an r-value. > > - Todd > > On Mon, 2006-07-24 at 19:16 +0200, Johannes Schlueter wrote: > > Hi, > > > > On Monday 24 July 2006 17:52, Rishad Omar wrote: > > > getArray($p = array()); > > > > Here you are relying on undefined behavior. It is not defined wether $p
=
> > array() or the function call getarray($p) should be executed first so
the

Ron Korving

20 years ago
in that case, the documentation on socket_select() needs to be edited: http://www.php.net/socket-select says: <?php /* Prepare the read array */ $read = array($socket1, $socket2); $num_changed_sockets = socket_select($read, $write = NULL, $except = NULL, 0); if ($num_changed_sockets === false) { /* Error handling */ } else if ($num_changed_sockets > 0) { /* At least at one of the sockets something interesting happened */ } ?> according to you, $write and $except could be undefined, right? - Ron "Johannes Schlueter" <johannes@php.net> wrote in message news:200607241916.27024.johannes@php.net...