FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » Imported messages » comp.lang.php » simple session question
Show: Today's Messages :: Polls :: Message Navigator
Switch to threaded view of this topic Create a new topic Submit Reply
simple session question [message #175695] Fri, 21 October 2011 17:44 Go to next message
cerr is currently offline  cerr
Messages: 33
Registered: September 2010
Karma: 0
Member
Hi There,

I'm a session newbie and got a (probably) simple question:
I have belowcode and i would expect stp to count up from 1 to 3 then
back to 1 when ever I reload this page but it for some reason always
stays at 0. Why that?

Thank you for assistance!

My code:

if(!isset($_SESSION['stp'])) {
session_start();
$_SESSION['stp'] = 0;
echo "session started<br>\n";
}
switch($_SESSION['stp']) {
case 0: $_SESSION['stp'] = $_SESSION['stp']++;
echo "stp:".$_SESSION['stp'];
break;
case 1: $_SESSION['stp'] = $_SESSION['stp']++;
echo "stp:".$_SESSION['stp'];
break;
case 2: $_SESSION['stp'] = $_SESSION['stp']++;
echo "stp:".$_SESSION['stp'];
$_SESSION['stp'] = 0;
break;
Re: simple session question [message #175696 is a reply to message #175695] Fri, 21 October 2011 18:19 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
cerr schrieb:

> if(!isset($_SESSION['stp'])) {
> session_start();
> $_SESSION['stp'] = 0;
> echo "session started<br>\n";
> }

You need to call session_start() on *every* page request, not just when
you initialize the session (think of it as
"session_start_or_continue()"). The $_SESSION superglobal does not exist
until you have called session_start(), so your code above won't work.

> switch($_SESSION['stp']) {
> case 0: $_SESSION['stp'] = $_SESSION['stp']++;
> echo "stp:".$_SESSION['stp'];
> break;
> case 1: $_SESSION['stp'] = $_SESSION['stp']++;
> echo "stp:".$_SESSION['stp'];
> break;
> case 2: $_SESSION['stp'] = $_SESSION['stp']++;
> echo "stp:".$_SESSION['stp'];
> $_SESSION['stp'] = 0;
> break;

You're missing a } here. But even with that and the session_start()
issue fixed, it always prints 0. I'm not quite sure why, but anyway your
code is unnecessarily complicated. Here's my version:

session_start();
if ( !isset( $_SESSION['stp'] ) )
{
$_SESSION['stp'] = 0;
echo "session started<br>\n";
}

echo $_SESSION['stp'];
$_SESSION['stp'] = ( $_SESSION['stp'] + 1 ) % 3;

I use the modulo operator % to achieve the cycling through the values 0,
1, 2.

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175697 is a reply to message #175696] Fri, 21 October 2011 18:51 Go to previous messageGo to next message
Jonathan Stein is currently offline  Jonathan Stein
Messages: 43
Registered: September 2010
Karma: 0
Member
Den 21-10-2011 20:19, Thomas Mlynarczyk skrev:

>> case 0: $_SESSION['stp'] = $_SESSION['stp']++;

With ++ after the variable, it is increased AFTER it has been used for
the calculation. So this happens:

1) The value of "$_SESSION['stp']++" is calculated. (Result: 0)

2) $_SESSION['stp'] is increased.

3) $_SESSION['stp'] is assigned the previously calculated value (zero).

It should work with ++$_SESSION['stp'], but still it's redundant to
assign the value of a variable to itself.

- And then the solution presented by Thomas is still far more elegant.

Regards

Jonathan
Re: simple session question [message #175698 is a reply to message #175697] Fri, 21 October 2011 20:00 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jonathan Stein schrieb:

> 1) The value of "$_SESSION['stp']++" is calculated. (Result: 0)
> 2) $_SESSION['stp'] is increased.
> 3) $_SESSION['stp'] is assigned the previously calculated value (zero).

Ah, thanks for helping me see through this. In other words:

$foo = 0;
$foo = $foo++;

is basically equivalent to

$foo = 0;
$tmp = $foo;
$foo = $foo + 1;
$foo = $tmp;

although one should probably not rely on that behaviour. This is
probably a good candidate for an obfuscated code contest.

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175699 is a reply to message #175698] Fri, 21 October 2011 20:14 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 10/21/2011 4:00 PM, Thomas Mlynarczyk wrote:
> Jonathan Stein schrieb:
>
>> 1) The value of "$_SESSION['stp']++" is calculated. (Result: 0)
>> 2) $_SESSION['stp'] is increased.
>> 3) $_SESSION['stp'] is assigned the previously calculated value (zero).
>
> Ah, thanks for helping me see through this. In other words:
>
> $foo = 0;
> $foo = $foo++;
>
> is basically equivalent to
>
> $foo = 0;
> $tmp = $foo;
> $foo = $foo + 1;
> $foo = $tmp;
>
> although one should probably not rely on that behaviour. This is
> probably a good candidate for an obfuscated code contest.
>
> Greetings,
> Thomas
>
>

The behavior is correct, and can be relied upon 100%.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: simple session question [message #175700 is a reply to message #175696] Fri, 21 October 2011 21:43 Go to previous messageGo to next message
cerr is currently offline  cerr
Messages: 33
Registered: September 2010
Karma: 0
Member
On Oct 21, 11:19 am, Thomas Mlynarczyk <tho...@mlynarczyk-
webdesign.de> wrote:
> cerr schrieb:
>
>> if(!isset($_SESSION['stp'])) {
>>   session_start();
>>   $_SESSION['stp'] = 0;
>>   echo "session started<br>\n";
>> }
>
> You need to call session_start() on *every* page request, not just when
> you initialize the session (think of it as
> "session_start_or_continue()"). The $_SESSION superglobal does not exist
> until you have called session_start(), so your code above won't work.
>
>> switch($_SESSION['stp']) {
>>   case 0: $_SESSION['stp'] = $_SESSION['stp']++;
>>              echo "stp:".$_SESSION['stp'];
>>              break;
>>   case 1: $_SESSION['stp'] = $_SESSION['stp']++;
>>              echo "stp:".$_SESSION['stp'];
>>              break;
>>   case 2: $_SESSION['stp'] = $_SESSION['stp']++;
>>              echo "stp:".$_SESSION['stp'];
>>           $_SESSION['stp'] = 0;
>>              break;
>
> You're missing a } here. But even with that and the session_start()
> issue fixed, it always prints 0. I'm not quite sure why, but anyway your
> code is unnecessarily complicated. Here's my version:
>
> session_start();
> if ( !isset( $_SESSION['stp'] ) )
> {
>      $_SESSION['stp'] = 0;
>      echo "session started<br>\n";
>
> }
>
> echo $_SESSION['stp'];
> $_SESSION['stp'] = ( $_SESSION['stp'] + 1 ) % 3;
>
> I use the modulo operator % to achieve the cycling through the values 0,
> 1, 2.
>

Weird, my phpinfo() says: "Session Support enabled"
but even with code like this
<?php
session_start();
echo ++$_SESSION['test'];
?>
just prints "session_start(); 1" - and i'm wondering why it's printing
session_start(); in the browser, seems like it doesn't know this
command...? Weird, any clues...?

Thanks alot!
Ron
Re: simple session question [message #175701 is a reply to message #175700] Fri, 21 October 2011 22:47 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
cerr schrieb:
> Weird, my phpinfo() says: "Session Support enabled"
> but even with code like this
> <?php
> session_start();
> echo ++$_SESSION['test'];
> ?>
> just prints "session_start(); 1" - and i'm wondering why it's printing
> session_start(); in the browser, seems like it doesn't know this
> command...? Weird, any clues...?

Strange. Here it works. (Except for the notice about the undefined index
'test' at the first call, but that is easily fixed and has nothing to do
with the problem.) If your PHP installation did not know the
session_start() function it would give you a fatal error. Is your above
code the exact same code (copy & paste) you were running?

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175702 is a reply to message #175699] Fri, 21 October 2011 22:50 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jerry Stuckle schrieb:

>> $foo = 0;
>> $foo = $foo++;
>>
>> is basically equivalent to
>>
>> $foo = 0;
>> $tmp = $foo;
>> $foo = $foo + 1;
>> $foo = $tmp;
>
> The behavior is correct, and can be relied upon 100%.

Is that mentioned somewhere in the manual? Anyway, to me, $foo = $foo++
looks like asking for trouble.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175703 is a reply to message #175702] Fri, 21 October 2011 23:05 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 10/21/2011 6:50 PM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
>>> $foo = 0;
>>> $foo = $foo++;
>>>
>>> is basically equivalent to
>>>
>>> $foo = 0;
>>> $tmp = $foo;
>>> $foo = $foo + 1;
>>> $foo = $tmp;
>>
>> The behavior is correct, and can be relied upon 100%.
>
> Is that mentioned somewhere in the manual? Anyway, to me, $foo = $foo++
> looks like asking for trouble.
>
> Greetings,
> Thomas
>

Yes, see how operator precedence works. It is well defined.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: simple session question [message #175704 is a reply to message #175700] Fri, 21 October 2011 23:06 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 10/21/2011 5:43 PM, h wrote:
> On Oct 21, 11:19 am, Thomas Mlynarczyk<tho...@mlynarczyk-
> webdesign.de> wrote:
>> cerr schrieb:
>>
>>> if(!isset($_SESSION['stp'])) {
>>> session_start();
>>> $_SESSION['stp'] = 0;
>>> echo "session started<br>\n";
>>> }
>>
>> You need to call session_start() on *every* page request, not just when
>> you initialize the session (think of it as
>> "session_start_or_continue()"). The $_SESSION superglobal does not exist
>> until you have called session_start(), so your code above won't work.
>>
>>> switch($_SESSION['stp']) {
>>> case 0: $_SESSION['stp'] = $_SESSION['stp']++;
>>> echo "stp:".$_SESSION['stp'];
>>> break;
>>> case 1: $_SESSION['stp'] = $_SESSION['stp']++;
>>> echo "stp:".$_SESSION['stp'];
>>> break;
>>> case 2: $_SESSION['stp'] = $_SESSION['stp']++;
>>> echo "stp:".$_SESSION['stp'];
>>> $_SESSION['stp'] = 0;
>>> break;
>>
>> You're missing a } here. But even with that and the session_start()
>> issue fixed, it always prints 0. I'm not quite sure why, but anyway your
>> code is unnecessarily complicated. Here's my version:
>>
>> session_start();
>> if ( !isset( $_SESSION['stp'] ) )
>> {
>> $_SESSION['stp'] = 0;
>> echo "session started<br>\n";
>>
>> }
>>
>> echo $_SESSION['stp'];
>> $_SESSION['stp'] = ( $_SESSION['stp'] + 1 ) % 3;
>>
>> I use the modulo operator % to achieve the cycling through the values 0,
>> 1, 2.
>>
>
> Weird, my phpinfo() says: "Session Support enabled"
> but even with code like this
> <?php
> session_start();
> echo ++$_SESSION['test'];
> ?>
> just prints "session_start(); 1" - and i'm wondering why it's printing
> session_start(); in the browser, seems like it doesn't know this
> command...? Weird, any clues...?
>
> Thanks alot!
> Ron

That's because the code you posted is not what you have in your script.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: simple session question [message #175705 is a reply to message #175696] Fri, 21 October 2011 21:17 Go to previous messageGo to next message
cerr is currently offline  cerr
Messages: 33
Registered: September 2010
Karma: 0
Member
On Oct 21, 11:19 am, Thomas Mlynarczyk <tho...@mlynarczyk-
webdesign.de> wrote:
> cerr schrieb:
>
>> if(!isset($_SESSION['stp'])) {
>>   session_start();
>>   $_SESSION['stp'] = 0;
>>   echo "session started<br>\n";
>> }
>
> You need to call session_start() on *every* page request, not just when
> you initialize the session (think of it as
> "session_start_or_continue()"). The $_SESSION superglobal does not exist
> until you have called session_start(), so your code above won't work.
>
>> switch($_SESSION['stp']) {
>>   case 0: $_SESSION['stp'] = $_SESSION['stp']++;
>>              echo "stp:".$_SESSION['stp'];
>>              break;
>>   case 1: $_SESSION['stp'] = $_SESSION['stp']++;
>>              echo "stp:".$_SESSION['stp'];
>>              break;
>>   case 2: $_SESSION['stp'] = $_SESSION['stp']++;
>>              echo "stp:".$_SESSION['stp'];
>>           $_SESSION['stp'] = 0;
>>              break;
>
> You're missing a } here. But even with that and the session_start()
> issue fixed, it always prints 0. I'm not quite sure why, but anyway your
> code is unnecessarily complicated. Here's my version:
>
> session_start();
> if ( !isset( $_SESSION['stp'] ) )
> {
>      $_SESSION['stp'] = 0;
>      echo "session started<br>\n";
>
> }
>
> echo $_SESSION['stp'];
> $_SESSION['stp'] = ( $_SESSION['stp'] + 1 ) % 3;
>
> I use the modulo operator % to achieve the cycling through the values 0,
> 1, 2.


Hi Thomas,

Thanks for the reply! Using your code, the variable always stays 0
too, it doesn't change ever. I always see "
session_start(); session started
0" printed, seems like it may not know sessions, is that possible at
all?

Thanks!
Ron
Re: simple session question [message #175706 is a reply to message #175702] Fri, 21 October 2011 23:32 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
>>> $foo = 0;
>>> $foo = $foo++;
>>>
>>> is basically equivalent to
>>>
>>> $foo = 0;
>>> $tmp = $foo;
>>> $foo = $foo + 1;
>>> $foo = $tmp;
>>
>> The behavior is correct, and can be relied upon 100%.
>
> Is that mentioned somewhere in the manual? Anyway, to me, $foo = $foo++
> looks like asking for trouble.
>

Why?

try $foo=($foo++);

But actually, why not just

$foo+=1;

or even

$foo++;

> Greetings,
> Thomas
>
Re: simple session question [message #175707 is a reply to message #175706] Sat, 22 October 2011 10:01 Go to previous messageGo to next message
Luuk is currently offline  Luuk
Messages: 329
Registered: September 2010
Karma: 0
Senior Member
On 22-10-2011 01:32, The Natural Philosopher wrote:
> try $foo=($foo++);
>
> But actually, why not just
>
> $foo+=1;

Because they differ?

$ php -r ' $foo=0; $foo=$foo++; print $foo."\n";'
0
$ php -r ' $foo=0; $foo=($foo++); print $foo."\n";'
0
$ php -r ' $foo=0; $foo++; print $foo."\n";'
1
$


--
Luuk
Re: simple session question [message #175708 is a reply to message #175706] Sat, 22 October 2011 13:39 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
The Natural Philosopher schrieb:

> try $foo=($foo++);
>
> But actually, why not just
>
> $foo+=1;

Well, as Luuk mentioned, they are not the same. And I almost never use
the increment/decrement operators. I prefer the form $foo += 1. What I
find confusing about $foo = $foo++ is that it is not intuitively clear
what it does. The OP had certainly intended "$foo++" (just increment
$foo), but PHP interprets the construct differently. In a way which
makes sense when you think about it, but which was not obvious to me
from the start. And I am still not sure that there is no optimizer or
similar extension that would optimize this construct to a simple $foo++.

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175709 is a reply to message #175703] Sat, 22 October 2011 13:40 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jerry Stuckle schrieb:
[$foo = $foo++;]
>> Is that mentioned somewhere in the manual?
> Yes, see how operator precedence works. It is well defined.

It is the internal order of execution that confuses me a bit. First, the
expression on the right is evaluated, yielding the "not-yet-incremented"
value. Then, two things must happen: Incrementing $foo and assigning
$foo the value from the first step. The result depends on the order of
these two steps. Clearly, the increment should happen before the next
read access to $foo. But whether or not it happens before the next write
access (assigning $foo the value from the first step) is neither
intuitively clear (and optimizers might handle this one way or the
other) nor explicitly stated in
<http://de3.php.net/manual/en/language.operators.increment.php>. There
is only a user comment saying: "The exact moment when post-increment and
post-decrement happen is _just immediately after the variable is
evaluated_ (not "after the line is processed" or something like that)".
If this is meant to be documented behaviour, they should mention it as
such in the manual.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175710 is a reply to message #175705] Sat, 22 October 2011 13:50 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
cerr schrieb:
>> session_start();
>> if ( !isset( $_SESSION['stp'] ) )
>> {
>> $_SESSION['stp'] = 0;
>> echo "session started<br>\n";
>>
>> }
>>
>> echo $_SESSION['stp'];
>> $_SESSION['stp'] = ( $_SESSION['stp'] + 1 ) % 3;

> Hi Thomas,
>
> Thanks for the reply! Using your code, the variable always stays 0
> too, it doesn't change ever. I always see "
> session_start(); session started
> 0" printed, seems like it may not know sessions, is that possible at
> all?

The only way I can see for this to happen is if you have the <?php
*after* the session_start() line, like this:

session_start();
<?php
if ( !isset( $_SESSION['stp'] ) ) // ...

If you have it as it should be --

<?php
session_start();
if ( !isset( $_SESSION['stp'] ) ) // ...

-- then there would be no way for "session_start()" to appear in the
output. If the counter then still remains at 0, you may have cookies
disabled in your browser.


Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175711 is a reply to message #175707] Sat, 22 October 2011 14:27 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
Luuk wrote:
> On 22-10-2011 01:32, The Natural Philosopher wrote:
>> try $foo=($foo++);
>>
>> But actually, why not just
>>
>> $foo+=1;
>
> Because they differ?
>
> $ php -r ' $foo=0; $foo=$foo++; print $foo."\n";'
> 0
> $ php -r ' $foo=0; $foo=($foo++); print $foo."\n";'
> 0

That is surely a bug..


> $ php -r ' $foo=0; $foo++; print $foo."\n";'
> 1
> $
>
>
Re: simple session question [message #175712 is a reply to message #175711] Sat, 22 October 2011 14:37 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
The Natural Philosopher wrote:
> Luuk wrote:
>> On 22-10-2011 01:32, The Natural Philosopher wrote:
>>> try $foo=($foo++);
>>>
>>> But actually, why not just
>>>
>>> $foo+=1;
>>
>> Because they differ?
>>
>> $ php -r ' $foo=0; $foo=$foo++; print $foo."\n";'
>> 0
>> $ php -r ' $foo=0; $foo=($foo++); print $foo."\n";'
>> 0
>
> That is surely a bug..
>

viz

~$ cat test.c
#include <stdio.h>
main()
{
int foo;
foo=0;
foo=(foo++);
printf("%d\n",foo);
}
~$ ./test
1


I thought PHP followed C operator precedence exactly..


>
>> $ php -r ' $foo=0; $foo++; print $foo."\n";'
>> 1
>> $
>>
>>
Re: simple session question [message #175713 is a reply to message #175712] Sat, 22 October 2011 15:08 Go to previous messageGo to next message
Luuk is currently offline  Luuk
Messages: 329
Registered: September 2010
Karma: 0
Senior Member
On 22-10-2011 16:37, The Natural Philosopher wrote:
> The Natural Philosopher wrote:
>> Luuk wrote:
>>> On 22-10-2011 01:32, The Natural Philosopher wrote:
>>>> try $foo=($foo++);
>>>>
>>>> But actually, why not just
>>>>
>>>> $foo+=1;
>>>
>>> Because they differ?
>>>
>>> $ php -r ' $foo=0; $foo=$foo++; print $foo."\n";'
>>> 0
>>> $ php -r ' $foo=0; $foo=($foo++); print $foo."\n";'
>>> 0
>>
>> That is surely a bug..
>>
>
> viz
>
> ~$ cat test.c
> #include <stdio.h>
> main()
> {
> int foo;
> foo=0;
> foo=(foo++);
> printf("%d\n",foo);
> }
> ~$ ./test
> 1
>
>
> I thought PHP followed C operator precedence exactly..
>
>

it seems to follow PERL

$ perl -e '$foo=0; $foo=$foo++; print $foo."\n";'
0
$ perl -e '$foo=0; $foo=($foo++); print $foo."\n";'
0
$ perl -e '$foo=0; $foo++; print $foo."\n";'
1
$


>>
>>> $ php -r ' $foo=0; $foo++; print $foo."\n";'
>>> 1
>>> $
>>>
>>>


--
Luuk
OT: and even in Dart .........Re: simple session question [message #175714 is a reply to message #175713] Sat, 22 October 2011 15:17 Go to previous messageGo to next message
Luuk is currently offline  Luuk
Messages: 329
Registered: September 2010
Karma: 0
Senior Member
On 22-10-2011 17:08, Luuk wrote:
> On 22-10-2011 16:37, The Natural Philosopher wrote:
>> The Natural Philosopher wrote:
>>> Luuk wrote:
>>>> On 22-10-2011 01:32, The Natural Philosopher wrote:
>>>> > try $foo=($foo++);
>>>> >
>>>> > But actually, why not just
>>>> >
>>>> > $foo+=1;
>>>>
>>>> Because they differ?
>>>>
>>>> $ php -r ' $foo=0; $foo=$foo++; print $foo."\n";'
>>>> 0
>>>> $ php -r ' $foo=0; $foo=($foo++); print $foo."\n";'
>>>> 0
>>>
>>> That is surely a bug..
>>>
>>
>> viz
>>
>> ~$ cat test.c
>> #include <stdio.h>
>> main()
>> {
>> int foo;
>> foo=0;
>> foo=(foo++);
>> printf("%d\n",foo);
>> }
>> ~$ ./test
>> 1
>>
>>
>> I thought PHP followed C operator precedence exactly..
>>
>>
>
> it seems to follow PERL
>
> $ perl -e '$foo=0; $foo=$foo++; print $foo."\n";'
> 0
> $ perl -e '$foo=0; $foo=($foo++); print $foo."\n";'
> 0
> $ perl -e '$foo=0; $foo++; print $foo."\n";'
> 1
> $
>
>

see: http://www.dartlang.org

main() {
int foo=0;
foo=foo++;
print('First test: ${foo}');

foo=0;
foo=(foo++);
print('Second test: ${foo}');

foo=0;
foo++;
print('Third test: ${foo}');

}

which gives:
First test: 0
Second test: 0
Third test: 1


--
Luuk
Re: OT: and even in Dart .........Re: simple session question [message #175715 is a reply to message #175714] Sat, 22 October 2011 15:54 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
Luuk wrote:
> On 22-10-2011 17:08, Luuk wrote:
>> On 22-10-2011 16:37, The Natural Philosopher wrote:
>>> The Natural Philosopher wrote:
>>>> Luuk wrote:
>>>> > On 22-10-2011 01:32, The Natural Philosopher wrote:
>>>> >> try $foo=($foo++);
>>>> >>
>>>> >> But actually, why not just
>>>> >>
>>>> >> $foo+=1;
>>>> >
>>>> > Because they differ?
>>>> >
>>>> > $ php -r ' $foo=0; $foo=$foo++; print $foo."\n";'
>>>> > 0
>>>> > $ php -r ' $foo=0; $foo=($foo++); print $foo."\n";'
>>>> > 0
>>>>
>>>> That is surely a bug..
>>>>
>>>
>>> viz
>>>
>>> ~$ cat test.c
>>> #include <stdio.h>
>>> main()
>>> {
>>> int foo;
>>> foo=0;
>>> foo=(foo++);
>>> printf("%d\n",foo);
>>> }
>>> ~$ ./test
>>> 1
>>>
>>>
>>> I thought PHP followed C operator precedence exactly..
>>>
>>>
>>
>> it seems to follow PERL
>>
>> $ perl -e '$foo=0; $foo=$foo++; print $foo."\n";'
>> 0
>> $ perl -e '$foo=0; $foo=($foo++); print $foo."\n";'
>> 0
>> $ perl -e '$foo=0; $foo++; print $foo."\n";'
>> 1
>> $
>>
>>
>
> see: http://www.dartlang.org
>
> main() {
> int foo=0;
> foo=foo++;
> print('First test: ${foo}');
>
> foo=0;
> foo=(foo++);
> print('Second test: ${foo}');
>
> foo=0;
> foo++;
> print('Third test: ${foo}');
>
> }
>
> which gives:
> First test: 0
> Second test: 0
> Third test: 1
>
>

still a bug in PHP where

"Parentheses may be used to force precedence, if necessary. For
instance: (1 + 5) * 3 evaluates to 18"

(from the manual)

I THOUGHT the general rule was that the value of (entity) was always the
FINAL value after ALL internal operations had been carried out.

Agreed its a crappy way to code, which is probably why no one has
noticed it.
Re: OT: and even in Dart .........Re: simple session question [message #175718 is a reply to message #175715] Sat, 22 October 2011 16:47 Go to previous messageGo to next message
Luuk is currently offline  Luuk
Messages: 329
Registered: September 2010
Karma: 0
Senior Member
On 22-10-2011 17:54, The Natural Philosopher wrote:
> Luuk wrote:
>> On 22-10-2011 17:08, Luuk wrote:
>>> On 22-10-2011 16:37, The Natural Philosopher wrote:
>>>> The Natural Philosopher wrote:
>>>> > Luuk wrote:
>>>> >> On 22-10-2011 01:32, The Natural Philosopher wrote:
>>>> >>> try $foo=($foo++);
>>>> >>>
>>>> >>> But actually, why not just
>>>> >>>
>>>> >>> $foo+=1;
>>>> >>
>>>> >> Because they differ?
>>>> >>
>>>> >> $ php -r ' $foo=0; $foo=$foo++; print $foo."\n";'
>>>> >> 0
>>>> >> $ php -r ' $foo=0; $foo=($foo++); print $foo."\n";'
>>>> >> 0
>>>> >
>>>> > That is surely a bug..
>>>> >
>>>>
>>>> viz
>>>>
>>>> ~$ cat test.c
>>>> #include <stdio.h>
>>>> main()
>>>> {
>>>> int foo;
>>>> foo=0;
>>>> foo=(foo++);
>>>> printf("%d\n",foo);
>>>> }
>>>> ~$ ./test
>>>> 1
>>>>
>>>>
>>>> I thought PHP followed C operator precedence exactly..
>>>>
>>>>
>>>
>>> it seems to follow PERL
>>>
>>> $ perl -e '$foo=0; $foo=$foo++; print $foo."\n";'
>>> 0
>>> $ perl -e '$foo=0; $foo=($foo++); print $foo."\n";'
>>> 0
>>> $ perl -e '$foo=0; $foo++; print $foo."\n";'
>>> 1
>>> $
>>>
>>>
>>
>> see: http://www.dartlang.org
>>
>> main() {
>> int foo=0;
>> foo=foo++;
>> print('First test: ${foo}');
>>
>> foo=0;
>> foo=(foo++);
>> print('Second test: ${foo}');
>>
>> foo=0;
>> foo++;
>> print('Third test: ${foo}');
>>
>> }
>>
>> which gives:
>> First test: 0
>> Second test: 0
>> Third test: 1
>>
>>
>
> still a bug in PHP where
>
> "Parentheses may be used to force precedence, if necessary. For
> instance: (1 + 5) * 3 evaluates to 18"
>
> (from the manual)
>
> I THOUGHT the general rule was that the value of (entity) was always the
> FINAL value after ALL internal operations had been carried out.
>
> Agreed its a crappy way to code, which is probably why no one has
> noticed it.

i did send a bug-report:
https://bugs.php.net/bug.php?id=60114

--
Luuk
Re: OT: and even in Dart .........Re: simple session question [message #175719 is a reply to message #175718] Sat, 22 October 2011 17:34 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Luuk schrieb:
> i did send a bug-report:
> https://bugs.php.net/bug.php?id=60114

I do not see any bug here. I was confused because it's a crappy way to
code, but it's clear why it works the way it does:

$foo = 0;
$foo = $foo++;

is definitely identical to

$foo = 0;
$foo = ($foo++);

since ++ has higher precedence than =. In fact, ($foo = $foo)++ does
rightfully throw a parse error, since you can only increment a variable,
not an expression.

As mentioned before in this thread, the above code is equivalent to

$foo = 0;
$tmp = $foo; // $foo++ yields the previous value, which is 0
$foo = $foo + 1; // then $foo is incremented...
$foo = $tmp; // ...and then re-assigned the old value

It's the exact same procedure as it would be with $foo = $bar++.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: OT: and even in Dart .........Re: simple session question [message #175724 is a reply to message #175719] Sat, 22 October 2011 20:08 Go to previous messageGo to next message
Norman Peelman is currently offline  Norman Peelman
Messages: 126
Registered: September 2010
Karma: 0
Senior Member
On 10/22/2011 01:34 PM, Thomas Mlynarczyk wrote:
> Luuk schrieb:
>> i did send a bug-report:
>> https://bugs.php.net/bug.php?id=60114
>
> I do not see any bug here. I was confused because it's a crappy way to
> code, but it's clear why it works the way it does:
>
> $foo = 0;
> $foo = $foo++;
>
> is definitely identical to
>
> $foo = 0;
> $foo = ($foo++);
>
> since ++ has higher precedence than =. In fact, ($foo = $foo)++ does
> rightfully throw a parse error, since you can only increment a variable,
> not an expression.
>
> As mentioned before in this thread, the above code is equivalent to
>
> $foo = 0;
> $tmp = $foo; // $foo++ yields the previous value, which is 0
> $foo = $foo + 1; // then $foo is incremented...
> $foo = $tmp; // ...and then re-assigned the old value
>
> It's the exact same procedure as it would be with $foo = $bar++.
>
> Greetings,
> Thomas
>

No they are not the same.

$foo = 0;
$foo = $foo++;

It should be equivalent to:

$foo = 0; // 0
$foo = $foo; // 0 = 0
$foo = $foo + 1; // 0 = (0 + 1)

$foo++ means that the variable is to be incremented after the variable
is accessed. Something is clobbering that increment.

++$foo means that the variable is to be incremented piror to the
variable being accessed. Works as expected.


Haven't seen the source code but there must be some temporary
variable that's getting clobbered for the $foo++ example.


--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: OT: and even in Dart .........Re: simple session question [message #175725 is a reply to message #175724] Sat, 22 October 2011 20:28 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 10/22/2011 4:08 PM, Norman Peelman wrote:
> On 10/22/2011 01:34 PM, Thomas Mlynarczyk wrote:
>> Luuk schrieb:
>>> i did send a bug-report:
>>> https://bugs.php.net/bug.php?id=60114
>>
>> I do not see any bug here. I was confused because it's a crappy way to
>> code, but it's clear why it works the way it does:
>>
>> $foo = 0;
>> $foo = $foo++;
>>
>> is definitely identical to
>>
>> $foo = 0;
>> $foo = ($foo++);
>>
>> since ++ has higher precedence than =. In fact, ($foo = $foo)++ does
>> rightfully throw a parse error, since you can only increment a variable,
>> not an expression.
>>
>> As mentioned before in this thread, the above code is equivalent to
>>
>> $foo = 0;
>> $tmp = $foo; // $foo++ yields the previous value, which is 0
>> $foo = $foo + 1; // then $foo is incremented...
>> $foo = $tmp; // ...and then re-assigned the old value
>>
>> It's the exact same procedure as it would be with $foo = $bar++.
>>
>> Greetings,
>> Thomas
>>
>
> No they are not the same.
>
> $foo = 0;
> $foo = $foo++;
>
> It should be equivalent to:
>
> $foo = 0; // 0
> $foo = $foo; // 0 = 0
> $foo = $foo + 1; // 0 = (0 + 1)
>
> $foo++ means that the variable is to be incremented after the variable
> is accessed. Something is clobbering that increment.
>
> ++$foo means that the variable is to be incremented piror to the
> variable being accessed. Works as expected.
>
>
> Haven't seen the source code but there must be some temporary variable
> that's getting clobbered for the $foo++ example.
>
>

Actually, I take my previous statement about the behavior being defined
back. Officially in C/C++, the results of this operation is undefined.

Precedence and associativity define the order in which operators are
processed. But the order of operand processing is not defined.

For

$foo = $foo++;

we have the same operand ($foo) being set twice. The $foo++ will return
0, and this value will be assigned into $foo.

But what is NOT defined is whether the assignment will occur before or
after the value of $foo is actually incremented. Either is possible.

Now in the case of

$foo = ($foo++);

The results are different, but they are still undefined.

In the first case the increment is obviously performed before the
assignment (although the assignment correctly uses the pre-increment value).

In the second case it looks like the assignment is still using the
pre-increment value, but the increment is done after the assignment.

Since the results are undefined, both are correct (or incorrect, as you
may look at it), and may change with changes to the interpreter (or
potentially the same version on different OS's).

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: simple session question [message #175727 is a reply to message #175709] Sat, 22 October 2011 21:19 Go to previous messageGo to next message
Richard Damon is currently offline  Richard Damon
Messages: 58
Registered: August 2011
Karma: 0
Member
On 10/22/11 9:40 AM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
> [$foo = $foo++;]
>>> Is that mentioned somewhere in the manual?
>> Yes, see how operator precedence works. It is well defined.
>
> It is the internal order of execution that confuses me a bit. First, the
> expression on the right is evaluated, yielding the "not-yet-incremented"
> value. Then, two things must happen: Incrementing $foo and assigning
> $foo the value from the first step. The result depends on the order of
> these two steps. Clearly, the increment should happen before the next
> read access to $foo. But whether or not it happens before the next write
> access (assigning $foo the value from the first step) is neither
> intuitively clear (and optimizers might handle this one way or the
> other) nor explicitly stated in
> <http://de3.php.net/manual/en/language.operators.increment.php>. There
> is only a user comment saying: "The exact moment when post-increment and
> post-decrement happen is _just immediately after the variable is
> evaluated_ (not "after the line is processed" or something like that)".
> If this is meant to be documented behaviour, they should mention it as
> such in the manual.
>
> Greetings,
> Thomas
>

I suspect that there is a difference between the execution model of
C/C++ and PHP here, do in part to the fact that C/C++ is (normally) a
compiled language with the goal of allowing the compiler to generate as
efficient of code as possible, while PHP is designed as a interpreted
language.

in C, x = x++; is undefined behavior, as the timing of when the =
operator is executed and the writing back of the value of x++ from the
++ operator is not specified, depending on when the compiler can most
efficiently implement it is ok. The code could be converted into the
equivalent of either.

temp = x; /* save original value of x */
x = x+1 /* perform increment */
x = temp; /* perform the = */

or
x = x; /* perform the = */
x = x+1; /* perform the ++ */

PHP doesn't seem to reserve for itself this ability, and there seems to
be some comments (which you refer to) asserting that x++ will ALWAY be
the equivalent of

temp = x;
x = x+1;
.... do what ever with temp

Which being an interpreted language makes some sense, why put off doing
something, and recording somewhere that you need to do it, when you can
do it now, the possible savings that C might have been able to make, get
swamped by the other overhead in PHP.

One thing is that we have a "formal spec" for the C language, created
and distributed by an international standard organization (ISO). is
there an equivalent of this for PHP, or do we only really have a single
implementation of PHP (in various versions), with "documentation" for
its behavior.
Re: OT: and even in Dart .........Re: simple session question [message #175729 is a reply to message #175719] Sat, 22 October 2011 21:47 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
Thomas Mlynarczyk wrote:
> Luuk schrieb:
>> i did send a bug-report:
>> https://bugs.php.net/bug.php?id=60114
>
> I do not see any bug here. I was confused because it's a crappy way to
> code, but it's clear why it works the way it does:
>
> $foo = 0;
> $foo = $foo++;
>
> is definitely identical to
>
> $foo = 0;
> $foo = ($foo++);

But it should NOT be. The brackets should force increment BEFORE
assignment.

As they do correctly in C.

I.er.
$foo Ok sop far

$foo++; // thats foo +1 when the dust settles although it as the
instantaneous valiue of foo. The +++ is the last thing that ghapp[ens

($foo++); // is an atomic expression meaning increment foo. Its value is
whatever the final final value of foo is.


>
> since ++ has higher precedence than =. In fact, ($foo = $foo)++ does
> rightfully throw a parse error, since you can only increment a variable,
> not an expression.
>

That's irrelevant.
<snip>
The point is that bracketing is supposed to absolutely ensure that
nothing outside gets done till the inside is complete.

So $a=($foo++); should be the same as
$foo++;
$a=$foo;
Re: OT: and even in Dart .........Re: simple session question [message #175730 is a reply to message #175724] Sat, 22 October 2011 21:52 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
Norman Peelman wrote:
> On 10/22/2011 01:34 PM, Thomas Mlynarczyk wrote:
>> Luuk schrieb:
>>> i did send a bug-report:
>>> https://bugs.php.net/bug.php?id=60114
>>
>> I do not see any bug here. I was confused because it's a crappy way to
>> code, but it's clear why it works the way it does:
>>
>> $foo = 0;
>> $foo = $foo++;
>>
>> is definitely identical to
>>
>> $foo = 0;
>> $foo = ($foo++);
>>
>> since ++ has higher precedence than =. In fact, ($foo = $foo)++ does
>> rightfully throw a parse error, since you can only increment a variable,
>> not an expression.
>>
>> As mentioned before in this thread, the above code is equivalent to
>>
>> $foo = 0;
>> $tmp = $foo; // $foo++ yields the previous value, which is 0
>> $foo = $foo + 1; // then $foo is incremented...
>> $foo = $tmp; // ...and then re-assigned the old value
>>
>> It's the exact same procedure as it would be with $foo = $bar++.
>>
>> Greetings,
>> Thomas
>>
>
> No they are not the same.
>
> $foo = 0;
> $foo = $foo++;
>
> It should be equivalent to:
>
> $foo = 0; // 0
> $foo = $foo; // 0 = 0
> $foo = $foo + 1; // 0 = (0 + 1)
>
> $foo++ means that the variable is to be incremented after the variable
> is accessed. Something is clobbering that increment.
>

No: increment is after assignment and the NEW value of foo is not being
incremented.

Without the brackets $foo=$foo++ should mean an unchanged foo..thats
perfectly legal.

Its the fact that the brackets don't force taking the value after
increment that is worrisome


I.e.

$ php -r ' $foo=0; $bar=(($foo++)); print $bar."\n";'
0
Re: simple session question [message #175731 is a reply to message #175727] Sat, 22 October 2011 21:56 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
Richard Damon wrote:
> On 10/22/11 9:40 AM, Thomas Mlynarczyk wrote:
>> Jerry Stuckle schrieb:
>> [$foo = $foo++;]
>>>> Is that mentioned somewhere in the manual?
>>> Yes, see how operator precedence works. It is well defined.
>>
>> It is the internal order of execution that confuses me a bit. First, the
>> expression on the right is evaluated, yielding the "not-yet-incremented"
>> value. Then, two things must happen: Incrementing $foo and assigning
>> $foo the value from the first step. The result depends on the order of
>> these two steps. Clearly, the increment should happen before the next
>> read access to $foo. But whether or not it happens before the next write
>> access (assigning $foo the value from the first step) is neither
>> intuitively clear (and optimizers might handle this one way or the
>> other) nor explicitly stated in
>> <http://de3.php.net/manual/en/language.operators.increment.php>. There
>> is only a user comment saying: "The exact moment when post-increment and
>> post-decrement happen is _just immediately after the variable is
>> evaluated_ (not "after the line is processed" or something like that)".
>> If this is meant to be documented behaviour, they should mention it as
>> such in the manual.
>>
>> Greetings,
>> Thomas
>>
>
> I suspect that there is a difference between the execution model of
> C/C++ and PHP here, do in part to the fact that C/C++ is (normally) a
> compiled language with the goal of allowing the compiler to generate as
> efficient of code as possible, while PHP is designed as a interpreted
> language.
>
> in C, x = x++; is undefined behavior, as the timing of when the =
> operator is executed and the writing back of the value of x++ from the
> ++ operator is not specified, depending on when the compiler can most
> efficiently implement it is ok. The code could be converted into the
> equivalent of either.
>

I dont think it is. The value of x is assigned before the increment
operator is applied: that's defined.


> temp = x; /* save original value of x */
> x = x+1 /* perform increment */
> x = temp; /* perform the = */
>
> or
> x = x; /* perform the = */
> x = x+1; /* perform the ++ */
>
> PHP doesn't seem to reserve for itself this ability, and there seems to
> be some comments (which you refer to) asserting that x++ will ALWAY be
> the equivalent of
>
> temp = x;
> x = x+1;
> ... do what ever with temp
>

BUT that doesnt cover the $bar=($foo++);

That should be
INC [foo]
MOV [bar].[foo];

NOT the other way around.

But in php it is.
Re: simple session question [message #175732 is a reply to message #175731] Sat, 22 October 2011 22:35 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
The Natural Philosopher schrieb:

> BUT that doesnt cover the $bar=($foo++);
>
> That should be
> INC [foo]
> MOV [bar].[foo];

That would be $bar = ( ++$foo );

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175733 is a reply to message #175731] Sat, 22 October 2011 22:43 Go to previous messageGo to next message
Tim Streater is currently offline  Tim Streater
Messages: 328
Registered: September 2010
Karma: 0
Senior Member
In article <j7ve6a$svk$1(at)news(dot)albasani(dot)net>,
The Natural Philosopher <tnp(at)invalid(dot)invalid> wrote:

> Richard Damon wrote:
>> On 10/22/11 9:40 AM, Thomas Mlynarczyk wrote:
>>> Jerry Stuckle schrieb:
>>> [$foo = $foo++;]
>>>> > Is that mentioned somewhere in the manual?
>>>> Yes, see how operator precedence works. It is well defined.
>>>
>>> It is the internal order of execution that confuses me a bit. First, the
>>> expression on the right is evaluated, yielding the "not-yet-incremented"
>>> value. Then, two things must happen: Incrementing $foo and assigning
>>> $foo the value from the first step. The result depends on the order of
>>> these two steps. Clearly, the increment should happen before the next
>>> read access to $foo. But whether or not it happens before the next write
>>> access (assigning $foo the value from the first step) is neither
>>> intuitively clear (and optimizers might handle this one way or the
>>> other) nor explicitly stated in
>>> <http://de3.php.net/manual/en/language.operators.increment.php>. There
>>> is only a user comment saying: "The exact moment when post-increment and
>>> post-decrement happen is _just immediately after the variable is
>>> evaluated_ (not "after the line is processed" or something like that)".
>>> If this is meant to be documented behaviour, they should mention it as
>>> such in the manual.
>>>
>>> Greetings,
>>> Thomas
>>>
>>
>> I suspect that there is a difference between the execution model of
>> C/C++ and PHP here, do in part to the fact that C/C++ is (normally) a
>> compiled language with the goal of allowing the compiler to generate as
>> efficient of code as possible, while PHP is designed as a interpreted
>> language.
>>
>> in C, x = x++; is undefined behavior, as the timing of when the =
>> operator is executed and the writing back of the value of x++ from the
>> ++ operator is not specified, depending on when the compiler can most
>> efficiently implement it is ok. The code could be converted into the
>> equivalent of either.
>>
>
> I dont think it is. The value of x is assigned before the increment
> operator is applied: that's defined.
>
>
>> temp = x; /* save original value of x */
>> x = x+1 /* perform increment */
>> x = temp; /* perform the = */
>>
>> or
>> x = x; /* perform the = */
>> x = x+1; /* perform the ++ */
>>
>> PHP doesn't seem to reserve for itself this ability, and there seems to
>> be some comments (which you refer to) asserting that x++ will ALWAY be
>> the equivalent of
>>
>> temp = x;
>> x = x+1;
>> ... do what ever with temp
>>
>
> BUT that doesnt cover the $bar=($foo++);
>
> That should be
> INC [foo]
> MOV [bar].[foo];
>
> NOT the other way around.
>
> But in php it is.

Mmmm. I'm not sure about that. In JavaScript (also interpreted) I do a
lot of:

i = 0;
first = results[i++];
second = results[i++];
etc

and first, second, get the zeroth and oneth elements of results,
respectively. So the ++ is done *after* the assignment.

--
Tim

"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
Re: OT: and even in Dart .........Re: simple session question [message #175734 is a reply to message #175724] Sat, 22 October 2011 22:56 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Norman Peelman schrieb:

> $foo = 0;
> $foo = $foo++;
>
> It should be equivalent to:
>
> $foo = 0; // 0
> $foo = $foo; // 0 = 0
> $foo = $foo + 1; // 0 = (0 + 1)

No. What you are doing here is assigning first and then incrementing.
The evaluation of $foo++ returns 0 and increments $foo as a side effect.
This evaluation process must be completed before the assignment can happen:

[1] Evaluate the expression $foo++ (result: 0, side effect: $foo = 1)
[2] Assign the result to $foo ($foo = 0)

> $foo++ means that the variable is to be incremented after the variable
> is accessed.

Yes, it means that the expression $foo++ evaluates to the value which
$foo had before. And it is this value which is assigned to $foo after
the $foo++ step is completed.

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: OT: and even in Dart .........Re: simple session question [message #175735 is a reply to message #175729] Sat, 22 October 2011 23:22 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
The Natural Philosopher schrieb:

> The point is that bracketing is supposed to absolutely ensure that
> nothing outside gets done till the inside is complete.

And that's exactly what happens:

// $foo = 0;
[1] Evaluate 0 // result: 0
[2] Assign result of [1] to $foo // $foo = 0
// $foo = ($foo++);
[3] Evaluate operation "post-increment" on $foo // ($foo++)
[3.1] Set return value to current $foo // result: 0
[3.2] Add 1 to $foo // $foo = 1
[3.3] Return result // 0
[4] Assign result of [3] to $foo // $foo = 0

Thus, for a few nanoseconds, $foo is indeed 1, until this increment is
undone in [4] by reassigning $foo its old value.

> So $a=($foo++); should be the same as
> $foo++;
> $a=$foo;

No. That would be $a = ++$foo.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: OT: and even in Dart .........Re: simple session question [message #175736 is a reply to message #175730] Sat, 22 October 2011 23:25 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
The Natural Philosopher schrieb:

> Its the fact that the brackets don't force taking the value after
> increment that is worrisome

Brackets get evaluated first. Result is the old value (since it's a
post-increment). Then, when all is done in the brackets (including the
increment), there's a 0 waiting on the RHS to be assigned.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175737 is a reply to message #175731] Sat, 22 October 2011 23:29 Go to previous messageGo to next message
Richard Damon is currently offline  Richard Damon
Messages: 58
Registered: August 2011
Karma: 0
Member
On 10/22/11 5:56 PM, The Natural Philosopher wrote:
> Richard Damon wrote:
>> On 10/22/11 9:40 AM, Thomas Mlynarczyk wrote:
>>> Jerry Stuckle schrieb:
>>> [$foo = $foo++;]
>>>> > Is that mentioned somewhere in the manual?
>>>> Yes, see how operator precedence works. It is well defined.
>>>
>>> It is the internal order of execution that confuses me a bit. First, the
>>> expression on the right is evaluated, yielding the "not-yet-incremented"
>>> value. Then, two things must happen: Incrementing $foo and assigning
>>> $foo the value from the first step. The result depends on the order of
>>> these two steps. Clearly, the increment should happen before the next
>>> read access to $foo. But whether or not it happens before the next write
>>> access (assigning $foo the value from the first step) is neither
>>> intuitively clear (and optimizers might handle this one way or the
>>> other) nor explicitly stated in
>>> <http://de3.php.net/manual/en/language.operators.increment.php>. There
>>> is only a user comment saying: "The exact moment when post-increment and
>>> post-decrement happen is _just immediately after the variable is
>>> evaluated_ (not "after the line is processed" or something like that)".
>>> If this is meant to be documented behaviour, they should mention it as
>>> such in the manual.
>>>
>>> Greetings,
>>> Thomas
>>>
>>
>> I suspect that there is a difference between the execution model of
>> C/C++ and PHP here, do in part to the fact that C/C++ is (normally) a
>> compiled language with the goal of allowing the compiler to generate
>> as efficient of code as possible, while PHP is designed as a
>> interpreted language.
>>
>> in C, x = x++; is undefined behavior, as the timing of when the =
>> operator is executed and the writing back of the value of x++ from the
>> ++ operator is not specified, depending on when the compiler can most
>> efficiently implement it is ok. The code could be converted into the
>> equivalent of either.
>>
>
> I dont think it is. The value of x is assigned before the increment
> operator is applied: that's defined.
>
>

Where do you see the definition of assignment first? In fact, from the
earlier examples, it is clear that at least those version of PHP did the
increment first.

The wording of the $a++ postfix operator is that it "Returns $a, then
increments $a by one." which if you want to be a stickler, requires the
interpreter to fork, as after the execution "returns" it can't continue
to do something. I think what they meant (as shown by the tests
upthread) that $a++ increments $a, but returns the value of saved value
of $a prior to the increment. To get an assignment comes first you would
need something like: returns the current value of $a and then at [what
here?] increments the value of $a. For [what here] you would need to add
something like Cs sequence points, for example in

$b = f($a++);

would $a be incremented before calling f, or after the assignment to $b?

>> temp = x; /* save original value of x */
>> x = x+1 /* perform increment */
>> x = temp; /* perform the = */
>>
>> or
>> x = x; /* perform the = */
>> x = x+1; /* perform the ++ */
>>
>> PHP doesn't seem to reserve for itself this ability, and there seems
>> to be some comments (which you refer to) asserting that x++ will ALWAY
>> be the equivalent of
>>
>> temp = x;
>> x = x+1;
>> ... do what ever with temp
>>
>
> BUT that doesnt cover the $bar=($foo++);
>
> That should be
> INC [foo]
> MOV [bar].[foo];
>
> NOT the other way around.
>
> But in php it is.

Putting $foo++ inside parens SHOULD change its meaning to ++$foo !!! The
value of the $foo++ operator is *always* the value of $foo before the
increment.

Parens force operators inside them to bind to operands before an
operator outside can bind to them. Let us say that * bound tighter than
++ (thankfully it doesn't, not much does)

then $a*$b++ would ordinarily be parsed the same as ($a*$b)++, (which
generates an error) but $a*($b++) generates what we normally want.


in the same way, fa()*(fb()+fc()), the () mean that we add the value of
fb() to fc() before we multiply by fa(). but does NOT imply that fa()
itself will be evaluated afterwards. To my knowledge, PHP does not
define the order that operands are evaluated in an expression, only the
precedence of the operators for which one binds tighter to the operand,
except for the logical operators which will always evaluate the left
operand first, and only if it then needs the value of the right operand,
evaluate that.
Re: OT: and even in Dart .........Re: simple session question [message #175738 is a reply to message #175725] Sat, 22 October 2011 23:39 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jerry Stuckle schrieb:
> But what is NOT defined is whether the assignment will occur before or
> after the value of $foo is actually incremented. Either is possible.

Yes, that was exactly what had confused me at first. But now I am
convinced that the most reasonable assumption is to increment at the
earliest possible moment, i.e. immediately after the result of the
expression $foo++ has been determined and before doing anything else.
After all, the RHS must be evaluated completely (including any side
effects this evaluation may have), before the result can be assigned to
the LHS. And wouldn't this also be the most simple implementation of the
evaluation algorithm? And it would allow for better optimization: the
statement $foo = $foo++; would be equivalent to a no op.

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175739 is a reply to message #175737] Sat, 22 October 2011 23:54 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Richard Damon schrieb:

> [...] To my knowledge, PHP does not
> define the order that operands are evaluated in an expression [...]

Okay, but it wouldn't make any difference for $foo = $foo++. Let's
rewrite this in pseudo-code:

$foo = 0;
assign( $foo, postincrement( $foo ) );

If we evaluate the operands of assign() in the specified order, we get 0
and 0. If we evaluate them in reverse order, we get 1 and 0. Since the
assignment simply overwrites the first operand's value, we end up with 0
in both cases.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175740 is a reply to message #175733] Sat, 22 October 2011 23:56 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Tim Streater schrieb:

> Mmmm. I'm not sure about that. In JavaScript (also interpreted) I do a
> lot of:
>
> i = 0;
> first = results[i++];
> second = results[i++];
> etc
>
> and first, second, get the zeroth and oneth elements of results,
> respectively. So the ++ is done *after* the assignment.

Yes. As long as you have two different operands, there is no problem.
But what does i = i++ do?

Greetings,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175741 is a reply to message #175727] Sun, 23 October 2011 00:12 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Richard Damon schrieb:

> I suspect that there is a difference between the execution model of
> C/C++ and PHP here, do in part to the fact that C/C++ is (normally) a
> compiled language with the goal of allowing the compiler to generate as
> efficient of code as possible, while PHP is designed as a interpreted
> language.

Hm. But PHP is written in C, so I would assume it to just follow C here.

> x = x; /* perform the = */
> x = x+1; /* perform the ++ */

That could be further optimized by dropping the x = x. But here the
assignment seems to have a higher precedence than the increment.

> temp = x;
> x = x+1;
> ... do what ever with temp
>
> Which being an interpreted language makes some sense, why put off doing
> something, and recording somewhere that you need to do it, when you can
> do it now, the possible savings that C might have been able to make, get
> swamped by the other overhead in PHP.

Now I wonder why x = x++ is undefined in C. If it was defined to be a no
op as it behaves in PHP, then it could be optimized away completely.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175742 is a reply to message #175741] Sun, 23 October 2011 01:13 Go to previous messageGo to previous message
Richard Damon is currently offline  Richard Damon
Messages: 58
Registered: August 2011
Karma: 0
Member
On 10/22/11 8:12 PM, Thomas Mlynarczyk wrote:
> Richard Damon schrieb:
>
>> I suspect that there is a difference between the execution model of
>> C/C++ and PHP here, do in part to the fact that C/C++ is (normally) a
>> compiled language with the goal of allowing the compiler to generate
>> as efficient of code as possible, while PHP is designed as a
>> interpreted language.
>
> Hm. But PHP is written in C, so I would assume it to just follow C here.
>
>> x = x; /* perform the = */
>> x = x+1; /* perform the ++ */
>
> That could be further optimized by dropping the x = x. But here the
> assignment seems to have a higher precedence than the increment.
>
>> temp = x;
>> x = x+1;
>> ... do what ever with temp
>>
>> Which being an interpreted language makes some sense, why put off
>> doing something, and recording somewhere that you need to do it, when
>> you can do it now, the possible savings that C might have been able to
>> make, get swamped by the other overhead in PHP.
>
> Now I wonder why x = x++ is undefined in C. If it was defined to be a no
> op as it behaves in PHP, then it could be optimized away completely.
>
> Greetings,
> Thomas
>

The issue is C is that there is a general rule (to allow optimizations)
that defines the behavior to be undefined if an expression causes a
variable to be written to twice, or have a read from and write to (where
the read from is not needed to determine the value to write to) without
an intervening sequence point, like the end of an expression.

The statement x = x++; has two different writes to x, so we meet the
requirement for undefined behavior. Not also that C does not limit when
the ++ part happens, only that this side effect will finish by the next
sequence point.

Part of the problem with this example is that it is a bit to simple, and
that simplicity hides some of the issues. Let us make the expression
just slightly more complicated to make it cleared. Let us use x = 5*x++;

This expression has two different value paths:

x = 5 * x; (the main expression) and
x = x + 1; (the side effect of x++)

The only ordering that C puts on these two expressions is that the read
for x in the first, must happen before the write of x in the second (due
to the definition of x++).

Thus in C the net expression is likely to be one of:

x = x+1; (if the first expression finishes first, and then the second,
using the original value of x)
x = 5*x; (if the second expression finishes first, and then the first,
using the original value of x)
x = 5*x+1; (if the first expression finishes first, and then the second,
using the new value of x)

It is even possible on some machines that the program will trap, as C
doesn't limit the possible effect on undefined behavior. This might
happen on a machine which is pipelined, and there is a restriction on
either writing a value and reading it back to quickly, or doing two
writes to closely.

This example may seem simple enough that the compiler should catch it,
but what if the statement was:

*y = x++;

and y just happened to point to x.

PHP, not trying to allow the compiler to generate as efficient code,
doesn't need to allow for the ambiguity in when the increment occurs,
and it makes sense to do it right away. Knowing C, I don't see them
making that explicit promise, but the way it is worded, if you didn't
know C, it seems to be what would be expected.
Pages (2): [1  2    »]  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: session cookie: client side
Next Topic: by get this format my explode file name like this through php
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Mon Nov 25 03:50:14 GMT 2024

Total time taken to generate the page: 0.03052 seconds