Req #70278 [Opn]: Allow null to be passed by reference
| From: | cyslider at posteo dot de | Date: | Sun, 16 Aug 2015 14:26:25 +0000 |
| Subject: | Req #70278 [Opn]: Allow null to be passed by reference | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-195246@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=70278&edit=1
ID: 70278
User updated by: cyslider at posteo dot de
Reported by: cyslider at posteo dot de
Summary: Allow null to be passed by reference
Status: Open
Type: Feature/Change Request
Package: *General Issues
PHP Version: Next Major Version
Block user comment: N
Private report: N
New Comment:
Thanks for the elaborate reply.
First of all lets not side track. My request was mainly for the null reference. The other request
was just a "nice-to-have" addition.
If I declare a function parameter as "Array &$array = null", however you may judge its
use, I expect it to be able to accept a direct "null" value. I don't see your other
arguments apply to this.
Anyhow:
> Nearly every function that "expects a reference merely for
> performance reasons" has been written wrong - in many
> cases, pass by reference actually has worse performance
> (the compiler is cleverer than people give it credit
> for). The language shouldn't be making such incorrect
> usage easier.
> There can be cases where you can avoid a copy-on-write
> using a reference param, but they should be carefully
> considered, and are unlikely to be in frequently-called
> code where creating a variable would be burdensome.
Ok, I know compilers have some dark magic tricks up their sleves and are awsome in this, but I
don't like to rely on some mechnisms that I do not fully understand. Anyhow, what you claim
sounds strange, copying faster than passing by reference? So I made a benchmark.
function testA(Array &$arr) {
return count($arr);
}
function testB(Array $arr) {
return count($arr);
}
$c = 0;
Utils::addTimestamp("Test A: Begin");
for ($i = 0; $i<10000000; $i++) {
// Huge array defined in 2000 lines of code.
$c += testA(Globals::$structure);
}
Utils::addTimestamp("Test A: End");
Utils::addTimestamp("Test B: Begin");
for ($i = 0; $i<10000000; $i++) {
$c += testB(Globals::$structure);
}
Utils::addTimestamp("Test B: End");
echo "Elements: ".($c/10000000);
Result:
[0.0982170105] +0.0035328865: Test A: Begin
[6.9941301346] +6.8959131241: Test A: End
[6.9941751957] +0.0000450611: Test B: Begin
[9.6694211960] +2.6752460003: Test B: End
So you were not simply right, its amazing 2-3 times faster than not using a reference!!
But to my understanding this can not so much be an intelligent compiler than a massive screwup in
the references implementation...
In one case it needs to copy a 2000 lines Array and in the other it has only to pass a small
reference??!?
What am I missing here?
> Most of the time, if a function is asking for something by
> reference, it should be because it's expecting to write
> back to that variable, so passing a non-variable makes no
> sense. For this case, the current behaviour is entirely
> correct.
I personally think in an object oriented language this should be achieved by passing objects instead
of directly passing literals as reference. I know this is a leftover of PHP 4 times, but nowerdays,
the only reason for me to use "by reference" on literals should be performance.
> Note that because your first example provides a default
> parameter value, you can just write testFunc(); anyway if
> you're not interested in the reference parameter.
I know that. This was just a quick example. In my case the parameter in question is in midst of
other parameters that need to be specified. The default parameter is just specified, because else
its not allowed to pass 'null' at all.
Beside that, often this functions are declared in includes so I have no control over how the
function is defined.
Anyhow, thanks for this yet again unexpected insight about PHP. Guess I have to rethink my strategy
reguarding references.... Alot....
Previous Comments:
------------------------------------------------------------------------
[2015-08-16 13:19:53] rowan dot collins at gmail dot com
Nearly every function that "expects a reference merely for performance reasons" has been
written wrong - in many cases, pass by reference actually has worse performance (the compiler is
cleverer than people give it credit for). The language shouldn't be making such incorrect usage
easier.
There can be cases where you can avoid a copy-on-write using a reference param, but they should be
carefully considered, and are unlikely to be in frequently-called code where creating a variable
would be burdensome.
Most of the time, if a function is asking for something by reference, it should be because it's
expecting to write back to that variable, so passing a non-variable makes no sense. For this case,
the current behaviour is entirely correct.
Note that because your first example provides a default parameter value, you can just write
testFunc(); anyway if you're not interested in the reference parameter.
------------------------------------------------------------------------
[2015-08-15 15:06:12] cyslider at posteo dot de
Description:
------------
Please allow null - and preferable also any other value - to be directly passed into a function that
expects a reference.
If I want to pass 'null' by reference I currently have to do it like this:
function testFunc(Array &$array = null) {
// Do something
}
$null = null;
testFunc($null);
This is cumbersome.
Better would be to also allow:
testFunc(null);
I would suggest some automatical boxing in case a direct value is passed instead of a referenceable
variable. That way you could also pass strings directly into a function that expects a reference
merely for performance reasons.
function exec (&$sql) {
//Execute SQL
}
exec("Select 1");
Which currently throws an error.
Greetings,
CySlider
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=70278&edit=1