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
Re: OT: and even in Dart .........Re: simple session question [message #175743 is a reply to message #175725] Sun, 23 October 2011 02:40 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 04:28 PM, Jerry Stuckle wrote:
> 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).
>

The problem seems to be that the post increment is being overwritten
as if:

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

Which I think someone else may have said.

--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: OT: and even in Dart .........Re: simple session question [message #175744 is a reply to message #175734] Sun, 23 October 2011 02:52 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 06:56 PM, Thomas Mlynarczyk wrote:
> 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.
Yes

> The evaluation of $foo++ returns 0 and increments $foo as a side effect.
Yes

> This evaluation process must be completed before the assignment can happen:
Yes

>
> [1] Evaluate the expression $foo++ (result: 0, side effect: $foo = 1)
Yes

> [2] Assign the result to $foo ($foo = 0)

But when you echo $foo on the next line it should equal 1. It's a
race condition as 0 is held in a temporary buffer, $foo is incremented,
and then $foo is assigned the temporary buffer. Thereby overwriting the
increment.


>
>> $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.
>

Not really *before*, i'd say *current* value.

> Greetings,
> Thomas
>
>


--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
Re: simple session question [message #175745 is a reply to message #175741] Sun, 23 October 2011 03:03 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 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
>

Because it's not a noop. The language only defined the order of
operator evaluation - not operand evaluation. Some C compilers will
return 0, others will return 1.

The problem here is you are setting the value in the operand ($!foo)
twice in the same expression. Results of such operations is always
undefined in C.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: OT: and even in Dart .........Re: simple session question [message #175746 is a reply to message #175743] Sun, 23 October 2011 03: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/22/2011 10:40 PM, Norman Peelman wrote:
> On 10/22/2011 04:28 PM, Jerry Stuckle wrote:
>> 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).
>>
>
> The problem seems to be that the post increment is being overwritten as if:
>
> $foo = 0;
> $tmp = $foo;
> $foo = $foo + 1;
> $foo = $tmp;
>
> Which I think someone else may have said.
>

It's not being "overwritten" - the operand is being changed twice in the
same expression, which is undefined in C.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: OT: and even in Dart .........Re: simple session question [message #175747 is a reply to message #175735] Sun, 23 October 2011 07:40 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:
> 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

Why would one do that..what 'return value' is that...

You are making the side effect of lower precedence than the bracket.
That is NEVER done.


> [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
>
Re: OT: and even in Dart .........Re: simple session question [message #175748 is a reply to message #175736] Sun, 23 October 2011 07:41 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:
> 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.
>

Not in C it aint.

> Greetings,
> Thomas
>
Re: simple session question [message #175749 is a reply to message #175742] Sun, 23 October 2011 07:44 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 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.


Forget the foo=foo++ and consider the cases

bar=foo++;
and
bar=(foo++).


In C they give different results. in PHP they do not.
Re: OT: and even in Dart .........Re: simple session question [message #175750 is a reply to message #175734] Sun, 23 October 2011 08:39 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 <j7vhmk$420$1(at)news(dot)albasani(dot)net>,
Thomas Mlynarczyk <thomas(at)mlynarczyk-webdesign(dot)de> wrote:

> 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.

Yes - as per my JavaScript example. If I say:

results[i++];

I get the value of results[i]. That value is held in limbo to be
assigned to the LHS. Then the post-increment occurs. Then the result
from limbo is assigned to LHS.

And so with PHP. Which will mean that:

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

both act the same and set $foo to 0.

--
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 #175751 is a reply to message #175750] Sun, 23 October 2011 08:40 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
Tim Streater wrote:
> In article <j7vhmk$420$1(at)news(dot)albasani(dot)net>,
> Thomas Mlynarczyk <thomas(at)mlynarczyk-webdesign(dot)de> wrote:
>
>> 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.
>
> Yes - as per my JavaScript example. If I say:
>
> results[i++];
>
> I get the value of results[i]. That value is held in limbo to be
> assigned to the LHS. Then the post-increment occurs. Then the result
> from limbo is assigned to LHS.
>
> And so with PHP. Which will mean that:
>
> $foo = $foo++;
> $foo = ($foo++);
>
> both act the same and set $foo to 0.
>
First I heard that []===().....
Re: OT: and even in Dart .........Re: simple session question [message #175752 is a reply to message #175751] Sun, 23 October 2011 08: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 <j80juf$nct$1(at)news(dot)albasani(dot)net>,
The Natural Philosopher <tnp(at)invalid(dot)invalid> wrote:

> Tim Streater wrote:
>> In article <j7vhmk$420$1(at)news(dot)albasani(dot)net>,
>> Thomas Mlynarczyk <thomas(at)mlynarczyk-webdesign(dot)de> wrote:
>>
>>> 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.
>>
>> Yes - as per my JavaScript example. If I say:
>>
>> results[i++];
>>
>> I get the value of results[i]. That value is held in limbo to be
>> assigned to the LHS. Then the post-increment occurs. Then the result
>> from limbo is assigned to LHS.
>>
>> And so with PHP. Which will mean that:
>>
>> $foo = $foo++;
>> $foo = ($foo++);
>>
>> both act the same and set $foo to 0.
>>
> First I heard that []===().....

Come again?

--
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 #175756 is a reply to message #175747] Sun, 23 October 2011 15:04 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:
>> // $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

> Why would one do that..what 'return value' is that...

It's the result of evaluating the expression $foo++. It must remember
the current value of $foo since that is what will be needed later. Why
"one" would do that? Well, PHP needs to evaluate $foo++ somehow, how
else is it supposed to work? The above algorithm is what PHP probably
does under the hood in order to produce the observed behaviour.

> You are making the side effect of lower precedence than the bracket.

No I'm not. With the above algorithm, the side effect happens well
inside the brackets, i.e. within the evaluation of $oo++ -- that's step
[3.2] below: increment $foo while still inside the evaluation routine
[3]. At that moment, $foo = 1 and "the brackets are done", returning the
evaluation result 0 in step [3.3].

> That is NEVER done.

My sketched algorithm does produce the observed result and is consistent
with the aforementioned user comment in the PHP manual.

>> [3.2] Add 1 to $foo // $foo = 1
>> [3.3] Return result // 0
>> [4] Assign result of [3] to $foo // $foo = 0

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 #175757 is a reply to message #175744] Sun, 23 October 2011 15:12 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:
>> [1] Evaluate the expression $foo++ (result: 0, side effect: $foo = 1)
>> [2] Assign the result to $foo ($foo = 0)

> But when you echo $foo on the next line it should equal 1. It's a race
> condition as 0 is held in a temporary buffer, $foo is incremented, and
> then $foo is assigned the temporary buffer. Thereby overwriting the
> increment.

And thus, echoing $foo should print 0. The temporary buffer is 0 and in
[2] $foo is assigned this value, "overwriting the increment" as you
write correctly. So why do you say that a subsequent echo $foo should
print 1? And in the above scenario there is no race condition involved.
There must be a misunderstanding of what you wrote on my part here.

>> 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.

> Not really *before*, i'd say *current* value.

Yes.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175758 is a reply to message #175749] Sun, 23 October 2011 15:31 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:
> Forget the foo=foo++ and consider the cases
>
> bar=foo++;
> and
> bar=(foo++).
>
> In C they give different results.

Interesting. If I remember correctly, ++ has higher precedence than = in
C as well. Therefore, I would assume that both statements above are the
same. Assuming foo = 0, bar should equal 0 in both cases and foo = 1.

But you seem to imply that bar = (foo++) is identical to bar = ++foo? In
that case I would find it very confusing.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175759 is a reply to message #175696] Sun, 23 October 2011 15:47 Go to previous messageGo to next message
Denis McMahon is currently offline  Denis McMahon
Messages: 634
Registered: September 2010
Karma: 0
Senior Member
On Fri, 21 Oct 2011 20:19:53 +0200, Thomas Mlynarczyk wrote:

> 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

Look at the start of his code.

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

He always starts a session, and part of his session startup sets stp to 0.

So stp is always reset to 0 when a session is [re]started, not just when
a new session is created.

Now look at his "case 0" code

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

The value of the expression "$_SESSION['stp']++" is the value of $_SESSION
['stp'] *before the increment operation*

eg, in:

x = y++;

x = original y
y = original y + 1

so he increments $_SESSION['stp'] and then assigns the value before it
was incremented back to the variable. As an aside, doing such things is
normally considered really really bad coding practice, as you can't
always guarantee that you'll get the same result, as you don't always
know which storage operation will occur last and thus determine the final
value of $_SESSION['stp']

e.g. the incremented value $_SESSION['stp']++ may be stored before or
after the evaluated expression $_SESSION['stp']= stores it's value. I
suspect that with c compilers, this would be an "undefined behaviour"
issue.

However, what's happening here is that by using a post increment, the
evaluation of the right side is the original value of the array element,
and that's the value that gets stored last.

So, he [re]starts the session, sets the 'stp' value to 0, increments it
and then over-writes the incremented value with the value before
incrementing, and finally:

>> echo "stp:".$_SESSION['stp'];

outputs the value, which is still 0.

And that, I suspect, is why he always gets a 0.

Basically, using:

x = x++;

is the headache, because in a single mathematical operation, you attempt
to define two conflicting values for x.

If he wants $_SESSION['stp'] to be 0 on the first pass and always
increment in the sequence 012012012 I'd do something like this:

session_start()
if(!isset($_SESSION['stp'])) {
$_SESSION['stp'] = 2;
echo "new session created<br>\n";
}
$_SESSION['stp'] = ($_SESSION['stp'] + 1) % 3;
echo "stp value is {$_SESSION['stp']}<br>\n";

I set the initial value to 2 so that the add 1, modulo 3 operation will
return a 0 on the first occasion after the variable is created. Setting
the initial value to -1 will also work. If the initial value is set to 0,
the value will be 1 after the increment, which may not be what the OP
expects the first time the page is loaded? Of course, this will be for
the OP to decide in the context of how he uses the stp value.

Rgds

Denis McMahon
Re: simple session question [message #175761 is a reply to message #175758] Sun, 23 October 2011 16:18 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:
> The Natural Philosopher schrieb:
>> Forget the foo=foo++ and consider the cases
>>
>> bar=foo++;
>> and
>> bar=(foo++).
>>
>> In C they give different results.
>
> Interesting. If I remember correctly, ++ has higher precedence than = in
> C as well. Therefore, I would assume that both statements above are the
> same. Assuming foo = 0, bar should equal 0 in both cases and foo = 1.
>
> But you seem to imply that bar = (foo++) is identical to bar = ++foo? In
> that case I would find it very confusing.
>

Odd. It doesn't do it for bar, but it does if foo=(foo++);

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

--------------------

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

Looks like its stepping off into 'indeterminate behaviour'
Re: simple session question [message #175762 is a reply to message #175742] Sun, 23 October 2011 17:00 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:

> 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.

So basically, it boils down to "programmer" vs. "compiler": The
programmer would like to have everything defined clearly, because
anything "undefined" simply means (s)he cannot use that construct. The
compiler, on the other hand, can work the better, the fewer restrictions
there are, and thus "welcomes" anything left undefined. And C focuses
more on the compiler, while PHP focuses more on the programmer.

> 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.

So in C, the statement x = x++ is regarded "as a whole" and the compiler
can do anything with it as long as certain constraints are observed,
while PHP, being a higher level language than C, must have all the tiny
internal steps well defined.

> 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++;

If I have understood you correctly, this would be

In PHP:
[1] $tmp = $x;
[2] $x = $x + 1;
[3] $tmp = 5 * $tmp;
[4] $x = $tmp;
In exactly that order (or maybe [2] and [3] swapped as it would make no
difference).

In C:
[TODO] RHS = 5 * (value of x before increment)
[TODO] increment x
[TODO] LHS = RHS
With the only restriction on the order being that the third item must
necessarily come after the first and it's up to the compiler to choose.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175763 is a reply to message #175745] Sun, 23 October 2011 17:06 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:

> The problem here is you are setting the value in the operand ($!foo)
> twice in the same expression. Results of such operations is always
> undefined in C.

In other words: if it were two different variables, like a = b++, there
would be no problem and the result would always be the same, so the
compiler can "choose" how it will do the work. And if there is then a
case where the two variables are the same, the compiler will just "do as
usual", but in this case the result will depend on how it does it.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175764 is a reply to message #175761] Sun, 23 October 2011 17:14 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:

> cat test.c
> #include <stdio.h>
> main()
> {
> int foo,bar;
> foo=0;
> bar=(foo++);
> printf("%d\n",bar);
> }
> $ make test
> cc test.c -o test
> $./test
> 0
>
> --------------------
>
> $ cat test.c
> #include <stdio.h>
> main()
> {
> int foo,bar;
> foo=0;
> foo=(foo++);
> printf("%d\n",foo);
> }
> $ make test
> cc test.c -o test
> $ ./test
> 1
>
> Looks like its stepping off into 'indeterminate behaviour'

So the lesson to be learnt here is what we all already knew: Don't do
$foo = $foo++.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: simple session question [message #175765 is a reply to message #175764] Sun, 23 October 2011 17:16 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:
> The Natural Philosopher schrieb:
>
>> cat test.c
>> #include <stdio.h>
>> main()
>> {
>> int foo,bar;
>> foo=0;
>> bar=(foo++);
>> printf("%d\n",bar);
>> }
>> $ make test
>> cc test.c -o test
>> $./test
>> 0
>>
>> --------------------
>>
>> $ cat test.c
>> #include <stdio.h>
>> main()
>> {
>> int foo,bar;
>> foo=0;
>> foo=(foo++);
>> printf("%d\n",foo);
>> }
>> $ make test
>> cc test.c -o test
>> $ ./test
>> 1
>>
>> Looks like its stepping off into 'indeterminate behaviour'
>
> So the lesson to be learnt here is what we all already knew: Don't do
> $foo = $foo++.
>
well being the worst typist ever, I never would as

$foo++;

is shorter.;)

> Greetings,
> Thomas
>
Re: simple session question [message #175768 is a reply to message #175763] Sun, 23 October 2011 18:35 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/23/2011 1:06 PM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
>> The problem here is you are setting the value in the operand ($!foo)
>> twice in the same expression. Results of such operations is always
>> undefined in C.
>
> In other words: if it were two different variables, like a = b++, there
> would be no problem and the result would always be the same, so the
> compiler can "choose" how it will do the work. And if there is then a
> case where the two variables are the same, the compiler will just "do as
> usual", but in this case the result will depend on how it does it.
>
> Greetings,
> Thomas
>

Exactly. When there are two variables, it doesn't matter whether the
actual increment of b is done before or after the assignment of the old
value into a.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: simple session question [message #175769 is a reply to message #175762] Sun, 23 October 2011 19:28 Go to previous messageGo to next message
Richard Damon is currently offline  Richard Damon
Messages: 58
Registered: August 2011
Karma: 0
Member
On 10/23/11 1:00 PM, Thomas Mlynarczyk wrote:
> Richard Damon schrieb:
>
>> 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.
>
> So basically, it boils down to "programmer" vs. "compiler": The
> programmer would like to have everything defined clearly, because
> anything "undefined" simply means (s)he cannot use that construct. The
> compiler, on the other hand, can work the better, the fewer restrictions
> there are, and thus "welcomes" anything left undefined. And C focuses
> more on the compiler, while PHP focuses more on the programmer.
>
>> 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.
>
> So in C, the statement x = x++ is regarded "as a whole" and the compiler
> can do anything with it as long as certain constraints are observed,
> while PHP, being a higher level language than C, must have all the tiny
> internal steps well defined.
>
>> 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++;
>
> If I have understood you correctly, this would be
>
> In PHP:
> [1] $tmp = $x;
> [2] $x = $x + 1;
> [3] $tmp = 5 * $tmp;
> [4] $x = $tmp;
> In exactly that order (or maybe [2] and [3] swapped as it would make no
> difference).
>
> In C:
> [TODO] RHS = 5 * (value of x before increment)
> [TODO] increment x
> [TODO] LHS = RHS
> With the only restriction on the order being that the third item must
> necessarily come after the first and it's up to the compiler to choose.
>
> Greetings,
> Thomas
>

Actually, both have the same basic steps (in principle)

(1) temp1 = x
(2) temp2 = x
(3) x = temp2 + 1
(4) temp3 = 5 * temp2
(5) x = temp3

(1 & 2 may be redundant and combined)
2,3 are the x++, 1,4,5 is the x = 5*x
by necessity we need the following order (can't use a value before it is
available)

1 -> 4 -> 5
2 -> 3
and by the definition of x++, 1 -> 3

PHP appears to define the order to be

1,2 -> 3 -> 4 -> 5

which means the increment of x is done tied to the fetching of the value
of x.

C places no additional restrictions on the order of the parts.

In particular, 3 can come before or after 5, and if 3 is after 5, 2 can
be before or after 5.
Re: OT: and even in Dart .........Re: simple session question [message #175909 is a reply to message #175715] Sat, 05 November 2011 20:00 Go to previous messageGo to next message
Peter H. Coffin is currently offline  Peter H. Coffin
Messages: 245
Registered: September 2010
Karma: 0
Senior Member
On Sat, 22 Oct 2011 16:54:11 +0100, 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.

The thing is that PHP is doing the right thing there. Remember that

$foo++

is not the same as

++$foo

The former "returns" the value PRIOR to incrementing, the latter AFTER
incrementing. Even wrapping $foo++ in parens won't change what it
returns. Don't use one when you want the other.

--
93. If I decide to hold a double execution of the hero and an underling
who failed or betrayed me, I will see to it that the hero is
scheduled to go first.
--Peter Anspach's list of things to do as an Evil Overlord
Re: OT: and even in Dart .........Re: simple session question [message #175910 is a reply to message #175724] Sat, 05 November 2011 20:04 Go to previous message
Peter H. Coffin is currently offline  Peter H. Coffin
Messages: 245
Registered: September 2010
Karma: 0
Senior Member
On Sat, 22 Oct 2011 16:08:01 -0400, 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.

Yes. The ASSIGNMENT back to $foo is clobbering it. The increment happens
immediately after access, before the VALUE is passed back to the
assignment.

> ++$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.

It's just happening in the proper order. increment happens before
assignment, exactly per
http://php.net/manual/en/language.operators.precedence.php

The catch is that the assignment is destroying the increment, because
the variable access happened BEFORE the increment.

--
17. When I employ people as advisors, I will occasionally listen to
their advice.
--Peter Anspach's list of things to do as an Evil Overlord
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:32:05 GMT 2024

Total time taken to generate the page: 0.03097 seconds