Hi all,
Take a look at this bug report.
https://bugs.php.net/bug.php?id=65087
He complains about documentation of ++/--.
The doc says
http://www.php.net/manual/en/language.operators.precedence.php
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
"may print 4 or 5"?? Undefined??
In old PHP there may be such limitation.
I cannot believe this is true now, but I ask list before I fix doc.
Any comments?
--
Yasuo Ohgaki
yohgaki@ohgaki.net
If run right now, it will always produce the same value (4), but it isn't
defined to do so. What that means is that behavior is subject to change
without notice, warning, or justification. This is a somewhat harsh way of
saying "Don't write expressions with ambiguous evaluations, that's clowny."
I would ask that you don't "fix" the docs, as we want to continue to
discourage users from engaging in unsafe behaviors.
Hi all,
Take a look at this bug report.
https://bugs.php.net/bug.php?id=65087
He complains about documentation of ++/--.
The doc sayshttp://www.php.net/manual/en/language.operators.precedence.php
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5"may print 4 or 5"?? Undefined??
In old PHP there may be such limitation.I cannot believe this is true now, but I ask list before I fix doc.
Any comments?
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Sara,
2013/7/20 Sara Golemon pollita@php.net
I would ask that you don't "fix" the docs, as we want to continue to
discourage users from engaging in unsafe behaviors.
If precedence is implemented correctly, there should not be any ambiguity.
If precedence is not implemented correctly, I suppose it is a bug as ++/--
have
much higher precedence.
We don't want such docs nor bugs, don't we?
Anyone know if the doc is correct or not?
Thanks in advance.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Sara,
2013/7/20 Sara Golemon pollita@php.net
I would ask that you don't "fix" the docs, as we want to continue to
discourage users from engaging in unsafe behaviors.If precedence is implemented correctly, there should not be any ambiguity.
If precedence is not implemented correctly, I suppose it is a bug as ++/--
have
much higher precedence.
I don't understand how it's a bug. Precedence is implemented correctly and
works as I'd expect it to. Here's the proof
http://3v4l.org/mR4da/vld#tabs
If you run this code through VLD you see that the opcodes clearly execute
both increment operators before the addition operator. This seems to hold
true from PHP 4.3.0 to 5.5.1 according to 3v4l.org. After all they do have
higher precedence in the precedence table.
$a = 1;
++$a // $a is now 2
$a++ // $a is still 2 and returns its value then increments to 3 (it's a
POST increment)
2 + 2 // The result is clearly 4
I would say that the behavior of these operators and their precedence is
very much well-defined. I don't see what the confusion.
We don't want such docs nor bugs, don't we?
Anyone know if the doc is correct or not?
Thanks in advance.
I don't see where there is a bug in the documentation, no.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Sherif,
Thank you for your info!
2013/7/20 Sherif Ramadan theanomaly.is@gmail.com
I don't see where there is a bug in the documentation, no.
It is in doc's example code.
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
http://www.php.net/manual/en/language.operators.precedence.php
I think ?: operator is good for an example, since it has different
associativity than C/C++.
If there aren't comments, I'll rewrite the example.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Sherif,
Thank you for your info!
2013/7/20 Sherif Ramadan theanomaly.is@gmail.com
I don't see where there is a bug in the documentation, no.
It is in doc's example code.
Then I would say that example is wrong, but people may find reason to
disagree. I'm basing my contention purely off what I see in php-src and the
documented behavior for those operators. To me I see no reason why this
behavior would be considered undefined. The ternary operator definitely has
some undefined behavior in terms of precedence since its interpreted as a
statement and not like other operators in expressions. To me post/pre
inc/dec are pretty well-defined.
I would say there is no harm in removing that comment from the
documentation.
Hi Sheif,
2013/7/20 Sherif Ramadan theanomaly.is@gmail.com
Then I would say that example is wrong, but people may find reason to
disagree. I'm basing my contention purely off what I see in php-src and the
documented behavior for those operators. To me I see no reason why this
behavior would be considered undefined. The ternary operator definitely has
some undefined behavior in terms of precedence since its interpreted as a
statement and not like other operators in expressions. To me post/pre
inc/dec are pretty well-defined.
I wasn't going to document ambiguity, but ?:
operator's association difference between C and PHP.
It's a common pitfall for C programmers when they use nested ternary
operators.
I would say there is no harm in removing that comment from the
documentation.
I agree.
I'll remove the example.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Sheif,
2013/7/20 Sherif Ramadan theanomaly.is@gmail.com
Then I would say that example is wrong, but people may find reason to
disagree. I'm basing my contention purely off what I see in php-src and the
documented behavior for those operators. To me I see no reason why this
behavior would be considered undefined. The ternary operator definitely has
some undefined behavior in terms of precedence since its interpreted as a
statement and not like other operators in expressions. To me post/pre
inc/dec are pretty well-defined.I wasn't going to document ambiguity, but ?:
operator's association difference between C and PHP.
It's a common pitfall for C programmers when they use nested ternary
operators.
Yea, I believe the documentation at php.net/ternary already advices against
nesting ternary in PHP. Honestly, I don't know how you would even put
ternary into the precedence table given that it reads more like a statement
and less like an operator. Just look at the implementation in the parser
and you will be left in wonderment.
Hi Sherif,
I changed the example as follows.
Thank you for your comment.
[yohgaki@dev en]$ svn diff
Index: language/operators.xml
--- language/operators.xml (リビジョン 330982)
+++ language/operators.xml (作業コピー)
@@ -225,15 +225,16 @@
</programlisting
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.
With all due respect, how is the behavior undefined? Our parser defines the
precedence of those operators being higher in the precedence table than the
ones mentioned. The post inc/dec operators are also well-defined in
returning their values "Returns $a, then increments $a by one." at
www.php.net/language.operators.increment
I present the source as well
http://lxr.php.net/xref/PHP_5_5/Zend/zend_compile.c#1196
I'm confused about why you believe this is undefined behavior? Perhaps you
can elaborate on why this should be left in the documentation as undefined
despite what I believe to be clear evidence of definition. I don't see
"discouraged behavior" and "undefined behavior" to be synonymous. I do feel
it's OK to place notes/warnings in the manual about discouraged behavior,
however, just as we do with nesting ternary operators.
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.
I'm with Sara on this one: you were too hasty to change the docs.
Hi Sara,
2013/7/20 Sara Golemon pollita@php.net
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.
If there is defined precedence, arithmetic operation should follow it.
If there is exception, it should be documented.
I don't understand why/how the arithmetic operation can be
ambiguous with defined precedence. (++ and -- are higher than +)
$a = 1;
echo ++$a + $a++;
should always print 4 with current PHP precedence definition.
If it does not, it's a bug in language.
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
I don't see any reason it became undefined.
If this kind of simple precedence is broken, how programmers write
code and/or trust the language?
http://3v4l.org/mR4da/vld#tabs
This site seems support PHP 4.3.0 to PHP 5.5.0 and opcode looks
fine. Am I missing something?
If you would like to suggest use of (), it should be done differently. IMHO.
The comment only ruins PHP's reputation as language.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
What's undefined isn't the relationship between preinc/postinc and add.
What's undefined is the use of multiple preinc/postinc operators within a
single expression (preincrements in particular). Our parser grammer, as it
currently stands, does have a predictable order, but that is a side-effect
of implementation. The language's definition of order of resolution of
multiple preinc/postinc elements within a single ticked statement is that
they are undefined. And that is what made your particular change to
the documentation incorrect.
If you'd like to define behavior for: echo ++$a + 1; then that's a
different matter. Defining the behavior of ++$a + $a++, however is
inviting misunderstanding*.
What was inappropriate, was asking for comment, receiving comment which
cited an issue, then committing without discussing that issue first.
-Sara
- Even if, technically, either order of evaluation will result in the same
answer for this contrived expression. ++$a * $a++ is a more obviously
ambiguous answer for a language which explicitly does not define an order
of resolution.
Hi Sara,
2013/7/20 Sara Golemon pollita@php.net
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.If there is defined precedence, arithmetic operation should follow it.
If there is exception, it should be documented.I don't understand why/how the arithmetic operation can be
ambiguous with defined precedence. (++ and -- are higher than +)$a = 1;
echo ++$a + $a++;should always print 4 with current PHP precedence definition.
If it does not, it's a bug in language.// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5I don't see any reason it became undefined.
If this kind of simple precedence is broken, how programmers write
code and/or trust the language?http://3v4l.org/mR4da/vld#tabs
This site seems support PHP 4.3.0 to PHP 5.5.0 and opcode looks
fine. Am I missing something?If you would like to suggest use of (), it should be done differently.
IMHO.
The comment only ruins PHP's reputation as language.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Sara,
What's undefined isn't the relationship between preinc/postinc and add.
What's undefined is the use of multiple preinc/postinc operators within a
single expression
I'm sorry but I can not find any evidence of how that is undefined. The
operators are right-associative, with a defined level or precedence. Their
operands are well defined and their return value in the expression is
determined by the compiler, not the parser. In this sense the compiler
always executes those opcodes first and returns a temporary variable.
(preincrements in particular). Our parser grammer, as it currently
stands, does have a predictable order, but that is a side-effect of
implementation. The language's definition of order of resolution of
multiple preinc/postinc elements within a single ticked statement is that
they are undefined. And that is what made your particular change to
the documentation incorrect.
The parser grammar in general is pretty muddled, I will agree with that.
However, the precedence order here is well defined within the expression. I
can not see any condition under which the compiler will introduce
unpredictable order of these opcodes or their results.
If you'd like to define behavior for: echo ++$a + 1; then that's a
different matter. Defining the behavior of ++$a + $a++, however is
inviting misunderstanding*.What was inappropriate, was asking for comment, receiving comment which
cited an issue, then committing without discussing that issue first.-Sara
- Even if, technically, either order of evaluation will result in the same
answer for this contrived expression. ++$a * $a++ is a more obviously
ambiguous answer for a language which explicitly does not define an order
of resolution.
By that logic we should indicate that -$a * $a is also undefined behavior?
I know the parser grammar is not well-defined and I'm taking this fact into
consideration, but here we are talking about operators which will compile
down into very much well-defined opcodes and have a predictable order of
resolution. It's quite possible that someone could introduce a change later
on that will cause a different result, but the likelihood of that becoming
a reality is slim-to-none.
I'm not a fan of getting into cat and mouse games over these types of
discussions, however. I posed my opinion on this matter and I refuse to
overwrite someone's commit because I feel my opinion is the only one that
counts. I am certainly not above being wrong. I just want to be sensible.
Hi Sara,
2013/7/20 Sara Golemon pollita@php.net
On Fri, Jul 19, 2013 at 7:16 PM, Yasuo Ohgaki yohgaki@ohgaki.netwrote:
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.If there is defined precedence, arithmetic operation should follow it.
If there is exception, it should be documented.I don't understand why/how the arithmetic operation can be
ambiguous with defined precedence. (++ and -- are higher than +)$a = 1;
echo ++$a + $a++;should always print 4 with current PHP precedence definition.
If it does not, it's a bug in language.// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5I don't see any reason it became undefined.
If this kind of simple precedence is broken, how programmers write
code and/or trust the language?http://3v4l.org/mR4da/vld#tabs
This site seems support PHP 4.3.0 to PHP 5.5.0 and opcode looks
fine. Am I missing something?If you would like to suggest use of (), it should be done differently.
IMHO.
The comment only ruins PHP's reputation as language.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
I'm disappointed $a+++++$a doesn't work as expected :(
Sara,
What's undefined isn't the relationship between preinc/postinc and add.
What's undefined is the use of multiple preinc/postinc operators within
a
single expressionI'm sorry but I can not find any evidence of how that is undefined. The
operators are right-associative, with a defined level or precedence. Their
operands are well defined and their return value in the expression is
determined by the compiler, not the parser. In this sense the compiler
always executes those opcodes first and returns a temporary variable.(preincrements in particular). Our parser grammer, as it currently
stands, does have a predictable order, but that is a side-effect of
implementation. The language's definition of order of resolution of
multiple preinc/postinc elements within a single ticked statement is that
they are undefined. And that is what made your particular change to
the documentation incorrect.The parser grammar in general is pretty muddled, I will agree with that.
However, the precedence order here is well defined within the expression. I
can not see any condition under which the compiler will introduce
unpredictable order of these opcodes or their results.If you'd like to define behavior for: echo ++$a + 1; then that's a
different matter. Defining the behavior of ++$a + $a++, however is
inviting misunderstanding*.What was inappropriate, was asking for comment, receiving comment which
cited an issue, then committing without discussing that issue first.-Sara
- Even if, technically, either order of evaluation will result in the
same
answer for this contrived expression. ++$a * $a++ is a more obviously
ambiguous answer for a language which explicitly does not define an order
of resolution.By that logic we should indicate that -$a * $a is also undefined behavior?
I know the parser grammar is not well-defined and I'm taking this fact into
consideration, but here we are talking about operators which will compile
down into very much well-defined opcodes and have a predictable order of
resolution. It's quite possible that someone could introduce a change later
on that will cause a different result, but the likelihood of that becoming
a reality is slim-to-none.I'm not a fan of getting into cat and mouse games over these types of
discussions, however. I posed my opinion on this matter and I refuse to
overwrite someone's commit because I feel my opinion is the only one that
counts. I am certainly not above being wrong. I just want to be sensible.On Fri, Jul 19, 2013 at 9:28 PM, Yasuo Ohgaki yohgaki@ohgaki.net
wrote:Hi Sara,
2013/7/20 Sara Golemon pollita@php.net
On Fri, Jul 19, 2013 at 7:16 PM, Yasuo Ohgaki <yohgaki@ohgaki.net
wrote:If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.If there is defined precedence, arithmetic operation should follow it.
If there is exception, it should be documented.I don't understand why/how the arithmetic operation can be
ambiguous with defined precedence. (++ and -- are higher than +)$a = 1;
echo ++$a + $a++;should always print 4 with current PHP precedence definition.
If it does not, it's a bug in language.// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5I don't see any reason it became undefined.
If this kind of simple precedence is broken, how programmers write
code and/or trust the language?http://3v4l.org/mR4da/vld#tabs
This site seems support PHP 4.3.0 to PHP 5.5.0 and opcode looks
fine. Am I missing something?If you would like to suggest use of (), it should be done differently.
IMHO.
The comment only ruins PHP's reputation as language.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Your example "-$a * $a" isn't at all the same because -$a doesn't produce
side-effects, only output.
I never said that the compiler might magically produce differing results
for the same input. I said that the language's definition does not declare
a defined behavior for such expressions with combined side effects.
As to reverting commits. When the initial commit was made in haste during
an active discussion, a revert is entirely appropriate and has nothing to
do with placing one's opinion over another's. It has to do with placing
the process of consensus building over unilateral cowboy commits.
-Sara
On Fri, Jul 19, 2013 at 10:08 PM, Sherif Ramadan theanomaly.is@gmail.comwrote:
Sara,
What's undefined isn't the relationship between preinc/postinc and add.
What's undefined is the use of multiple preinc/postinc operators within a
single expressionI'm sorry but I can not find any evidence of how that is undefined. The
operators are right-associative, with a defined level or precedence. Their
operands are well defined and their return value in the expression is
determined by the compiler, not the parser. In this sense the compiler
always executes those opcodes first and returns a temporary variable.(preincrements in particular). Our parser grammer, as it currently
stands, does have a predictable order, but that is a side-effect of
implementation. The language's definition of order of resolution of
multiple preinc/postinc elements within a single ticked statement is that
they are undefined. And that is what made your particular change to
the documentation incorrect.The parser grammar in general is pretty muddled, I will agree with that.
However, the precedence order here is well defined within the expression. I
can not see any condition under which the compiler will introduce
unpredictable order of these opcodes or their results.If you'd like to define behavior for: echo ++$a + 1; then that's a
different matter. Defining the behavior of ++$a + $a++, however is
inviting misunderstanding*.What was inappropriate, was asking for comment, receiving comment which
cited an issue, then committing without discussing that issue first.-Sara
- Even if, technically, either order of evaluation will result in the
same answer for this contrived expression. ++$a * $a++ is a more obviously
ambiguous answer for a language which explicitly does not define an order
of resolution.By that logic we should indicate that -$a * $a is also undefined behavior?
I know the parser grammar is not well-defined and I'm taking this fact into
consideration, but here we are talking about operators which will compile
down into very much well-defined opcodes and have a predictable order of
resolution. It's quite possible that someone could introduce a change later
on that will cause a different result, but the likelihood of that becoming
a reality is slim-to-none.I'm not a fan of getting into cat and mouse games over these types of
discussions, however. I posed my opinion on this matter and I refuse to
overwrite someone's commit because I feel my opinion is the only one that
counts. I am certainly not above being wrong. I just want to be sensible.Hi Sara,
2013/7/20 Sara Golemon pollita@php.net
On Fri, Jul 19, 2013 at 7:16 PM, Yasuo Ohgaki yohgaki@ohgaki.netwrote:
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.If there is defined precedence, arithmetic operation should follow it.
If there is exception, it should be documented.I don't understand why/how the arithmetic operation can be
ambiguous with defined precedence. (++ and -- are higher than +)$a = 1;
echo ++$a + $a++;should always print 4 with current PHP precedence definition.
If it does not, it's a bug in language.// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5I don't see any reason it became undefined.
If this kind of simple precedence is broken, how programmers write
code and/or trust the language?http://3v4l.org/mR4da/vld#tabs
This site seems support PHP 4.3.0 to PHP 5.5.0 and opcode looks
fine. Am I missing something?If you would like to suggest use of (), it should be done differently.
IMHO.
The comment only ruins PHP's reputation as language.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
(Piggy-backing on Sara's e-mail, although this is more a response to
Sherif and Yasuo.)
I never said that the compiler might magically produce differing results
for the same input. I said that the language's definition does not declare
a defined behavior for such expressions with combined side effects.
This is also a classic piece of undefined behaviour in most C-like
languages — Bjarne Stroustrup lists it in his C++ FAQ, for instance:
http://www.stroustrup.com/bs_faq2.html#evaluation-order. That's not to
say that PHP necessarily has to be the same as other languages in its
"family" (nested ternaries, anyone?), but I don't think that PHP is
really doing anything different here that would make it well defined:
AFAIK, the only places PHP makes guarantees about the order of
evaluation with regard to binary operators is short circuiting the
boolean operators.
As to reverting commits. When the initial commit was made in haste during
an active discussion, a revert is entirely appropriate and has nothing to
do with placing one's opinion over another's. It has to do with placing
the process of consensus building over unilateral cowboy commits.
+1.
Adam
Your example "-$a * $a" isn't at all the same because -$a doesn't produce
side-effects, only output.
It doesn't have side effects. This is true. So I retract my argument there.
I never said that the compiler might magically produce differing results
for the same input. I said that the language's definition does not declare
a defined behavior for such expressions with combined side effects.
While this is very true it's also a matter of discretion, because the
language doesn't clearly define a lot of things. In fact, one can argue
that there is no language definition at all since PHP doesn't even have a
spec. Though I'm trying to take common sense into consideration and make an
exception that in this case I don't see where removing the comment of
undefined behavior is going to necessarily cause more harm than good. Since
in the case of undefined behavior people will be left to wonder (why
doesn't ever seem to print 5?) We should either elaborate on why it might
print 5 in a full note on that page or we should remove the comment
completely. I oppose a documentation that leaves much room for clarity.
But perhaps for me it was easier to suggest removing the comment than
trying to clarify on why the behavior is undefined.
As to reverting commits. When the initial commit was made in haste during
an active discussion, a revert is entirely appropriate and has nothing to
do with placing one's opinion over another's. It has to do with placing
the process of consensus building over unilateral cowboy commits.
Fair enough.
-Sara
On Fri, Jul 19, 2013 at 10:08 PM, Sherif Ramadan theanomaly.is@gmail.comwrote:
Sara,
What's undefined isn't the relationship between preinc/postinc and add.
What's undefined is the use of multiple preinc/postinc operators within a
single expressionI'm sorry but I can not find any evidence of how that is undefined. The
operators are right-associative, with a defined level or precedence. Their
operands are well defined and their return value in the expression is
determined by the compiler, not the parser. In this sense the compiler
always executes those opcodes first and returns a temporary variable.(preincrements in particular). Our parser grammer, as it currently
stands, does have a predictable order, but that is a side-effect of
implementation. The language's definition of order of resolution of
multiple preinc/postinc elements within a single ticked statement is that
they are undefined. And that is what made your particular change to
the documentation incorrect.The parser grammar in general is pretty muddled, I will agree with that.
However, the precedence order here is well defined within the expression. I
can not see any condition under which the compiler will introduce
unpredictable order of these opcodes or their results.If you'd like to define behavior for: echo ++$a + 1; then that's a
different matter. Defining the behavior of ++$a + $a++, however is
inviting misunderstanding*.What was inappropriate, was asking for comment, receiving comment which
cited an issue, then committing without discussing that issue first.-Sara
- Even if, technically, either order of evaluation will result in the
same answer for this contrived expression. ++$a * $a++ is a more obviously
ambiguous answer for a language which explicitly does not define an order
of resolution.By that logic we should indicate that -$a * $a is also undefined
behavior? I know the parser grammar is not well-defined and I'm taking this
fact into consideration, but here we are talking about operators which will
compile down into very much well-defined opcodes and have a predictable
order of resolution. It's quite possible that someone could introduce a
change later on that will cause a different result, but the likelihood of
that becoming a reality is slim-to-none.I'm not a fan of getting into cat and mouse games over these types of
discussions, however. I posed my opinion on this matter and I refuse to
overwrite someone's commit because I feel my opinion is the only one that
counts. I am certainly not above being wrong. I just want to be sensible.On Fri, Jul 19, 2013 at 9:28 PM, Yasuo Ohgaki yohgaki@ohgaki.netwrote:
Hi Sara,
2013/7/20 Sara Golemon pollita@php.net
On Fri, Jul 19, 2013 at 7:16 PM, Yasuo Ohgaki yohgaki@ohgaki.netwrote:
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.If there is defined precedence, arithmetic operation should follow it.
If there is exception, it should be documented.I don't understand why/how the arithmetic operation can be
ambiguous with defined precedence. (++ and -- are higher than +)$a = 1;
echo ++$a + $a++;should always print 4 with current PHP precedence definition.
If it does not, it's a bug in language.// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5I don't see any reason it became undefined.
If this kind of simple precedence is broken, how programmers write
code and/or trust the language?http://3v4l.org/mR4da/vld#tabs
This site seems support PHP 4.3.0 to PHP 5.5.0 and opcode looks
fine. Am I missing something?If you would like to suggest use of (), it should be done differently.
IMHO.
The comment only ruins PHP's reputation as language.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
While this is very true it's also a matter of discretion, because the
language doesn't clearly define a lot of things. In fact, one can argue
that there is no language definition at all since PHP doesn't even have a
spec. Though I'm trying to take common sense into consideration and make an
exception that in this case I don't see where removing the comment of
undefined behavior is going to necessarily cause more harm than good. Since
in the case of undefined behavior people will be left to wonder (why
doesn't ever seem to print 5?) We should either elaborate on why it might
print 5 in a full note on that page or we should remove the comment
completely. I oppose a documentation that leaves much room for clarity.But perhaps for me it was easier to suggest removing the comment than
trying to clarify on why the behavior is undefined.
The language spec is a combination of the grammar and the documentation.
The documentation has stated this is undefined for a long time now. The
reasoning behind it was that since C and C++ both quite explicitly state
this is undefined and since implementations of PHP are likely to be in C
and C++ chances were pretty good that this undefined behaviour would end
up being inherited. Now, as it turns out, we haven't had that many
implementations of the language. But, there have been some. Also,
optimizers could potentially do something intelligent here that could
potentially change the outcome.
-Rasmus
Hi Sara,
2013/7/20 Sara Golemon pollita@php.net
What's undefined isn't the relationship between preinc/postinc and add.
What's undefined is the use of multiple preinc/postinc operators within a
single expression (preincrements in particular). Our parser grammer, as it
currently stands, does have a predictable order, but that is a side-effect
of implementation. The language's definition of order of resolution of
multiple preinc/postinc elements within a single ticked statement is that
they are undefined. And that is what made your particular change to
the documentation incorrect.If you'd like to define behavior for: echo ++$a + 1; then that's a
different matter. Defining the behavior of ++$a + $a++, however is
inviting misunderstanding*.What was inappropriate, was asking for comment, receiving comment which
cited an issue, then committing without discussing that issue first.-Sara
- Even if, technically, either order of evaluation will result in the
same answer for this contrived expression. ++$a * $a++ is a more obviously
ambiguous answer for a language which explicitly does not define an order
of resolution.
++/-- can be problematic for compilers when it is applied to in the same
arithmetic operator.
I can agree with this. It depends on compiler implementation.
I understand you suggesting users are suggested not to use -- ++ for the
same vars on the same arithmetic operations.
Is this correct?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.
Besides that, asking for comments and committing the same day is not
really conductive to a good discussion. Even if nobody objected - which
explicitly wasn't the case - there's nothing that prevented waiting for
a couple of days just to be sure. Please, let us not to be too hasty.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi Stas,
2013/7/20 Stas Malyshev smalyshev@sugarcrm.com
Hi!
If there aren't comments, I'll rewrite the example.
There were comments. I explicitly told you that that the behavior is
defined as undefined. You CHOSE to ignore that comment. You CHOSE to
break the documentation.Besides that, asking for comments and committing the same day is not
really conductive to a good discussion. Even if nobody objected - which
explicitly wasn't the case - there's nothing that prevented waiting for
a couple of days just to be sure. Please, let us not to be too hasty.
Fair discussion. I'll revert the commit for now.
Keeping room for better compilers is good, too.
Anyway, the restriction is needed to be documented.
How about this explanation?
<?php
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
// ternary operator associativity differs from C/C++
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
// mixing ++/-- and arithmetic operators may produce
// unexpected results, since the evaluation order depends
// on compiler implementation.
$a = 1;
echo ++$a + $a++; // not supported
?>
If expression like "echo ++$a + $a++" is not supported for future
compilers, PHP is better to raise E_NOTICE
if it is easy and fast.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi all,
Explanation for undefined behaviors.
=======================
// If a side effect on a variable is unsequenced relative to another
// side effect on the same variable, the behavior is undefined.
$i = 1;
$i = ++$i + $i++; // undefined behavior
$i = $i++ + 1; // undefined behavior (but $i = ++$i + 1; is
well-defined)
f(++$i, ++$i); // undefined behavior
f($i = -1, $i = -1); // undefined behavior
// If a side effect on a varible is unsequenced relative to a value
// computation using the value of the same variable, the behavior
// is undefined.
$a[$i] = $i++; // undefined behavior
If there are more of these, please point it out.
The cause of confusion is the fact that these are not about precedence.
It would better to have dedicated section for undefined behaviors, IHMO.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
I cannot believe this is true now, but I ask list before I fix doc.
I don't think there's something that needs to be fixed. "Undefined"
means "it depends on implementation and we do not want to commit to a
specific behavior here because implementations may change". This is a
fair warning against using implementation details that are not promised
to stay fixed and later crying why next PHP version broke your code.
Because you used undefined behavior. If the behavior is specified as
undefined, that means "don't do this" - so you know it may be broken,
and write better code instead that is not broken.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Sat, Jul 20, 2013 at 3:37 AM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
I cannot believe this is true now, but I ask list before I fix doc.
I don't think there's something that needs to be fixed. "Undefined"
means "it depends on implementation and we do not want to commit to a
specific behavior here because implementations may change". This is a
fair warning against using implementation details that are not promised
to stay fixed and later crying why next PHP version broke your code.
Because you used undefined behavior. If the behavior is specified as
undefined, that means "don't do this" - so you know it may be broken,
and write better code instead that is not broken.
Stas,
I agree that we should not rush to commit changes in the midst of on-going
discussion. However, I have to just add to this notion of undefined
behavior that by your definition ALL of PHP is undefined behavior.
Everything we do is an implementation detail. What specification do we have
that clearly defines PHP's behavior? Can you honestly tell me that we
haven't changed behavior in the past despite no clear warning of "undefined
behavior" in the manual? References being one example.
I'm just suggesting that we carefully consider our arguments and not only
acknowledge them when they work out to our benefit and then discard them
the moment they don't support our cause. Clearly there is an argument here
that this is acceptable behavior and clearly there is an argument that it
is undefined. The real question is whether or not its worth specifying as
"undefined behavior" in the manual. A single line comment in an example
like that which states "may print 4 or 5" is not good documentation. My
suggestion is either clarify in an actual note or section of that
documentation why it is considered undefined behavior or to remove the
comment.
There is unquestionable signs of confusion coming from our users as the bug
report indicates. We should not ignore the fact that this comment has
confused somebody and should instead strive to improve it.
My suggestion would be to ad some clarifying language here:
"Using multiple increment/decrement operators in the same expression has
no guaranteed order of resolution and is subject to change. Relying on code
such as $a = 1; ++$a + $a++ === 4; is considered undefined behavior."
Hi!
I agree that we should not rush to commit changes in the midst of
on-going discussion. However, I have to just add to this notion of
undefined behavior that by your definition ALL of PHP is undefined
behavior. Everything we do is an implementation detail. What
This is certainly not true. There's a lot of things explicitly
documented about PHP behavior, and those behaviors are well-defined.
specification do we have that clearly defines PHP's behavior? Can you
honestly tell me that we haven't changed behavior in the past despite no
Of course we changed behavior - languages change. We try not to change
documented behaviors, but in some occasions it is necessary. In this
case we tell people "we changed behavior because of these reasons".
Undefined behavior, on the other hand, can change anytime without much
notice and it is not considered BC break.
clear warning of "undefined behavior" in the manual? References being
one example.
One example of what?
argument that it is undefined. The real question is whether or not its
worth specifying as "undefined behavior" in the manual. A single line
There's no question here. We know it depends on internal implementation
and we know we do not want to commit to keeping specific behavior
exhibited now forever. This is what the manual is telling, and unless
you have some argument on why we must commit to it, it is not a
question, it is a fact about the state of affairs right now.
"Using multiple increment/decrement operators in the same expression has
no guaranteed order of resolution and is subject to change. Relying on
code such as $a = 1; ++$a + $a++ === 4; is considered undefined behavior."
If you want to rewrite the text to make the points about what undefined
behavior is clearer - sure, please do it. However, it should still say
this behavior is undefined and you should avoid relying on current
implementation if you want your code to be robust.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
After some digging and a little more thought I find that removing this
comment from the example in the docs at
www.php.net/language.operators.precedence does indeed cause more harm than
good. So I'm definitely wrong in saying that it should be removed.
However, I would like to acknowledge the confusion evident in bug 65087 and
offer some clarifying language and examples that may assist future users as
well as bring some closure to this bug report.
As pointed out to me on IRC PHP has exhibited changes in this behavior
between PHP < 5.1.0 and PHP >= 5.1.0 where the order of evaluation is not
well-defined. The example states that ++$a + $a++ may result in 4 or 5 and
that the behavior is undefined. This by itself seems confusing to the user
since they always see 4. What's not clear is that this isn't typical
everywhere in PHP.
For example:
$i = 0;
$i = $i++;
Here $i is always 0, but again the behavior is undefined because in the
following code it is not clear what happens:
$i = 0;
$arr = array();
$arr[$i] = $i++;
var_dump($arr);
According to the above code produces the following result between PHP
4.3.1 and 5.5.1
array(1) { [0]=> int(0) }
Where as the same code produces a very different result between PHP 5.1.0
and above:
array(1) { [1]=> int(0) }
The same happens with preinc/dec operators as well
$i = 0; $arr = array(); $arr[$i] = ++$i; var_dump($arr);
PHP < 5.1.0
array(1) { [0]=> int(1) }
PHP >= 5.1.0
array(1) { [1]=> int(1) }
The problem is I'm not sure where this type of information should be
documented. It makes sense to put this on the increment/decrement operators
page, but doesn't seem appropriate the operator precedence page. So to make
sure we're all in agreement I'm suggesting the following language to be
added as a note on the increment/decrement operators page at
www.php.net/language.operators.increment with supplement examples provided
above to help users get a better understanding of what we mean when we say
undefined behavior and add an additional warning box not to rely on this
type of behavior.
"As noted from the examples above the use of multiple increment/decrement
operators in the same expression is considered undefined behavior because
the order of evaluation cannot be guaranteed. Using such evaluations may
lead to unexpected results."
"Warning:
Relying on this behavior is discouraged as it may be subject to change and
without notice. Results are not typical and are implementation-specific."
If anyone feels that could use a little more clarity or can be reworded
better let me know. Thanks.
Hi all,
2013/7/21 Sherif Ramadan theanomaly.is@gmail.com
The problem is I'm not sure where this type of information should be
documented. It makes sense to put this on the increment/decrement operators
page, but doesn't seem appropriate the operator precedence page. So to make
sure we're all in agreement I'm suggesting the following language to be
added as a note on the increment/decrement operators page at
www.php.net/language.operators.increment with supplement examples
provided above to help users get a better understanding of what we mean
when we say undefined behavior and add an additional warning box not to
rely on this type of behavior.
Since the issue int "++$a + $a++" is not a precedence issue, but a
evaluation orders and side effects. Describing it without complete
explanation in precedence section makes users confuse. (I'm the one also)
I partially agree that documenting the issue in
www.php.net/language.operators.increment . It would better to be described
fully in a section since it is not a increment/decrement only issue.
"As noted from the examples above the use of multiple increment/decrement
operators in the same expression is considered undefined behavior because
the order of evaluation cannot be guaranteed. Using such evaluations may
lead to unexpected results.""Warning:
Relying on this behavior is discouraged as it may be subject to change and
without notice. Results are not typical and are implementation-specific."
These will fit into www.php.net/language.operators.increment.
If PHP is going to inherit C/C++ feature for better compiler implementation
and parallelism, we should document fully.
(Note: Java/C# seem always evaluate left to right and side effect is
immediately visible. Therefore, Java/C# don't have undefined behaviors like
C/C++. It's possible to behave like Java/C#, but PHP is going to follow
C/C++ way I suppose.)
http://en.cppreference.com/w/cpp/language/eval_order
- Between the previous and next sequence point a scalar object shall have
its stored value modified at most once by the evaluation of an expression.
i = ++i + i++; // undefined behavior
i = i++ + 1; // undefined behavior
i = ++i + 1; // undefined behavior (well-defined in C++11)
++ ++i; // undefined behavior (well-defined in C++11)
f(++i, ++i); // undefined behavior
f(i = -1, i = -1); // undefined behavior - Between the previous and next sequence point , the prior value of a
scalar object that is modified by the evaluation of the expression, shall
be accessed only to determine the value to be stored.
cout << i << i++; // undefined behavior
a[i] = i++; // undefined bevahior
In PHP, it would be
$i = ++$i + $i++;
$i = $i++ + 1;
$i = ++$i + 1;
++ ++$i;
f(++$i, ++$i); // This is good for parallelism. e.g. parameter evaluation
can be done in parallel. f(complex_func(), extremely_complex_func());
f($i = -1, $i = -1); // Same as above
echo $i, $i++; // Same as above
$a[$i] = $i++;
The best benefit of undefined evaluation order is parallelism (i.e. out of
order execution) even if PHP doesn't have it now. C/C++ doesn't execute
function parameters in parallel automatically, but PHP doesn't have to
follow this.
It would be good to have dedicated section for this. Discussion would be
needed if PHP is going to support out of order execution for func(f1(),
f2(), f3()) or like, which one make undefined, adding more undefined, etc.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
-----Original Message-----
From: yohgaki@gmail.com [mailto:yohgaki@gmail.com] On Behalf Of
Yasuo OhgakiHi all,
2013/7/21 Sherif Ramadan theanomaly.is@gmail.com
The problem is I'm not sure where this type of information should
be
documented. It makes sense to put this on the increment/decrement
operators
page, but doesn't seem appropriate the operator precedence page.
So to make
sure we're all in agreement I'm suggesting the following language
to be
added as a note on the increment/decrement operators page at
www.php.net/language.operators.increment with supplement examples
provided above to help users get a better understanding of what we
mean
when we say undefined behavior and add an additional warning box
not to
rely on this type of behavior.Since the issue int "++$a + $a++" is not a precedence issue, but a
evaluation orders and side effects. Describing it without complete
explanation in precedence section makes users confuse. (I'm the one
also)I partially agree that documenting the issue in
www.php.net/language.operators.increment . It would better to be
described
fully in a section since it is not a increment/decrement only issue.
I agree with this, mostly. It might well be appropriate to document that,
as a general rule, there is no guarantee in which order the operands of
an arithmetic (at least) operator are evaluated. And you are quite right
that it's not only increment/decrement operators, although those are the
most obvious culprits. Take the following (very contrived!) example:
function f($n) { echo $n; return $n; }
$x = f(1) + f(2);
For the same reason that the ++$a + $a++ example is undefined, it's
undefined whether that will echo 12 or 21 -- even though it's perfectly
well defined that $x will be 3 in either case! For this reason, I'd
probably go with the major warning being on the precedence/associativity
table, with a prominent reference to it on the ++/-- page.
Just my £0.02!
Cheers!
Mike
--
Mike Ford,
Electronic Information Developer, Libraries and Learning Innovation,
403a Leslie Silver Building, City Campus, Leeds Metropolitan University,
Woodhouse Lane, LEEDS, LS1 3ES, United Kingdom
E: m.ford@leedsmet.ac.uk T: +44 113 812 4730
To view the terms under which this email is distributed, please go to http://disclaimer.leedsmet.ac.uk/email.htm