Home > Archive > PERL Beginners > October 2006 > Evaluation of ++ different in C and perl?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Evaluation of ++ different in C and perl?
|
|
| Norbert Preining 2006-10-19, 7:56 am |
| Hi all!
Maybe this has been answered before, but my searching didn't show up
anything: The Perl Book says: Auto increment and decrement work as in C.
So if I take this C program:
#include <stdio.h>
#include <stddef.h>
int main() {
int a;
int b;
a=3;
b=(++a)+(a++);
printf("b=%d\n",b);
}
it prints b=8.
When I do the same in perl:
$a = 3;
$b = (++$a) + ($a++);
print "b=$b\n";
It prints b=9.
I checked with a friend and Java behaves like C and prints 8.
Can someone enlighten us by giving an interpretation of the above term?
Thanks a lot and all the best
Norbert
------------------------------------------------------------------------
Dr. Norbert Preining <preining@logic.at> Università di Siena
Debian Developer <preining@debian.org> Debian TeX Group
gpg DSA: 0x09C5B094
fp: 14DF 2E6C 0307 BE6D AD76 A9C0 D2BF 4AA3 09C5 B094
-------------------------------------------------------------------------
| |
| Jenda Krynicky 2006-10-19, 7:56 am |
| To: beginners@perl.org
Date sent: Thu, 19 Oct 2006 13:55:45 +0200
From: Norbert Preining <preining@logic.at>
Copies to: Elisa Mori <morie@unisi.it>, preining@logic.at
Subject: Evaluation of ++ different in C and perl?
> Hi all!
> Maybe this has been answered before, but my searching didn't show up
> anything: The Perl Book says: Auto increment and decrement work as in
> C. So if I take this C program: #include <stdio.h> #include <stddef.h>
> int main() {
> int a;
> int b;
> a=3;
> b=(++a)+(a++);
> printf("b=%d\n",b);
> }
> it prints b=8.
>
> When I do the same in perl:
> $a = 3;
> $b = (++$a) + ($a++);
> print "b=$b\n";
>
> It prints b=9.
>
> I checked with a friend and Java behaves like C and prints 8.
>
> Can someone enlighten us by giving an interpretation of the above
> term?
Anyone who uses something like that begs for problems.
Just don't do that.
Jenda
===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery
| |
| Paul Lalli 2006-10-19, 7:56 am |
| Norbert Preining wrote:
> When I do the same in perl:
> $a = 3;
> $b = (++$a) + ($a++);
> print "b=$b\n";
>
> It prints b=9.
> Can someone enlighten us by giving an interpretation of the above term?
When investigating a piece of code you don't understand, make it as
simple as possible.
Take a look at these two examples, based on yours above:
$ perl -le'
$a = 3;
$b = 0 + ($a++);
print "b=$b, a=$a";
'
b=3, a=4
$ perl -le'
$a = 3;
$b = $a + ($a++);
print "b=$b, a=$a";
'
b=7, a=4
What this tells us is that the $a++ is in fact returning 3, as it's
documented to. Then after it has returned 3, it increments $a to 4.
Then the *first* $a in the expression is evaluated. By this point, $a
is already 4. So we get the first $a, which has been incremented to 4,
and the $a++, which returned 3, summed to return 7.
Paul Lalli
| |
| Dr.Ruud 2006-10-19, 6:56 pm |
| Norbert Preining schreef:
> The Perl Book says: Auto increment and decrement work as in
> C. So if I take this C program:
> #include <stdio.h>
> #include <stddef.h>
> int main() {
> int a;
> int b;
> a=3;
> b=(++a)+(a++);
> printf("b=%d\n",b);
> }
> it prints b=8.
>
> When I do the same in perl:
> $a = 3;
> $b = (++$a) + ($a++);
> print "b=$b\n";
>
> It prints b=9.
>
> I checked with a friend and Java behaves like C and prints 8.
$ perl -wle '
$a = 3;
$b = 0 + (++$a) + ($a++);
print "b=$b\n";
'
b=8
:)
--
Affijn, Ruud
"Gewoon is een tijger."
| |
| Derek B. Smith 2006-10-19, 6:56 pm |
| --- "Dr.Ruud" <rvtol+news@isolution.nl> wrote:
> Norbert Preining schreef:
>
> work as in
> and prints 8.
>
> $ perl -wle '
> $a = 3;
> $b = 0 + (++$a) + ($a++);
> print "b=$b\n";
> '
> b=8
> :)
>
> --
> Affijn, Ruud
>
> "Gewoon is een tijger."
>
Lessons learned....
always initialize your variables to zero. : )
________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
| |
| Rob Dixon 2006-10-19, 6:56 pm |
| Derek B. Smith wrote:
> --- "Dr.Ruud" <rvtol+news@isolution.nl> wrote:
>
>
>
> Lessons learned....
>
> always initialize your variables to zero. : )
That's not initialising the variable, its, sort of, initialising the expression.
$b = 0;
$b += ++$a + $a++;
(the parentheses are irrelevant) also gives 9. This looks like a bug to me, and
v5.6 does it as well. Unless anyone can persuade me that this is correct
behaviour?
Rob
| |
| Norbert Preining 2006-10-19, 6:56 pm |
| Dr.Ruud wrote:
> $ perl -wle '
> $a = 3;
> $b = 0 + (++$a) + ($a++);
> print "b=$b\n";
> '
> b=8
> :)
Nup, this is not the solution:
$a = 3;
$b = 0;
$b = 0 + (++$a) + ($a++);
$c = 3;
$d = 0;
$d = (++$c) + ($c++);
print "b=$b\n";
print "d=$d\n";
prints:
b=8
d=9
Don't tell me that in perl
0 + somethingnumerical != somethingnumerical
So it is NOT dependent on the inizialization!
Ciao
Norbert
| |
| Derek B. Smith 2006-10-19, 6:56 pm |
| --- Rob Dixon <rob.dixon@350.com> wrote:
> Derek B. Smith wrote:
>
>
> That's not initialising the variable, its, sort of,
> initialising the expression.
>
> $b = 0;
> $b += ++$a + $a++;
>
> (the parentheses are irrelevant) also gives 9. This
> looks like a bug to me, and
> v5.6 does it as well. Unless anyone can persuade me
> that this is correct
> behaviour?
>
> Rob
>
No I cannot, you are correct...init the expression. :
)
Have to remember this one.
I tried in on Active Perl 5.8.8 and Cygwin 5.8.7 and
it is behaving the same way.
________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
| |
| Tom Phoenix 2006-10-19, 6:56 pm |
| On 10/19/06, Norbert Preining <preining@logic.at> wrote:
> $b = (++$a) + ($a++);
I'm not sure whether C does so, but I believe that Perl does NOT
promise that auto-increments will be executed in the "expected"
left-to-right order. Thus, if a single expression includes more than
one auto-increment working on the same variable, generally you can't
be sure what Perl will do with it. As you found.
Did this come up in a real-world situation, or were you specifically
s ing to test the limits of Perl? In other words, what problem, if
any, are you trying to solve?
Cheers!
--Tom Phoenix
Stonehenge Perl Training
| |
| Uri Guttman 2006-10-19, 6:56 pm |
| >>>>> "RD" == Rob Dixon <rob.dixon@350.com> writes:
RD> $b = 0;
RD> $b += ++$a + $a++;
RD> (the parentheses are irrelevant) also gives 9. This looks like a
RD> bug to me, and v5.6 does it as well. Unless anyone can persuade me
RD> that this is correct behaviour?
it is undefined behavior in most langs. the ordering of side effects is
not specified in perl and can vary from version to version. and other
langs (notably c) don't specify ordering. so the answer is (as was
said), DON'T DO THAT. there is almost no reason to do multiple side
effects where the ordering matters. if you want ordering use the
syntactical construct which is designed for that - a set of ordered
statements separated by sequence controlling semicolons.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
| |
| Norbert Preining 2006-10-19, 6:56 pm |
| Derek B. Smith wrote:
> Lessons learned....
>
> always initialize your variables to zero. : )
As I wrote, this is not the lesson. Even with initialization we have the
same!
Ciao
Norbert
| |
| lawrence@cluon.com 2006-10-19, 6:56 pm |
|
Tom writes:
> I'm not sure whether C does so, but I believe that Perl does NOT
> promise that auto-increments will be executed in the "expected"
> left-to-right order. Thus, if a single expression includes more than
> one auto-increment working on the same variable, generally you can't
> be sure what Perl will do with it. As you found.
In the C standard, the behaviour for
int a = 1, b;
b = ++a + a++;
is *undefined*.
Perfectly standards-compliant C compilers can perform any of the
following actions with equal validity:
* the compiler can dump core, and produce no output.
* at run time, the program can halt printing "Do not be a loser!"
* it can return "42"
* it can return '2' (1 + 1) and then increment a twice.
* it can - through blind stupid luck - return 5
See the comp.lang.c faq Questions 3.2 et seq. and comp.lang.c faq
question 11.33
Short answer: In C, Don't Do That. By extension, don't do it in Perl.
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Lawrence Statton - lawrenabae@abaluon.abaom s/aba/c/g
Computer software consists of only two components: ones and
zeros, in roughly equal proportions. All that is required is to
sort them into the correct order.
| |
| Rob Dixon 2006-10-19, 6:56 pm |
| Tom Phoenix wrote:
> On 10/19/06, Norbert Preining <preining@logic.at> wrote:
>
>
> I'm not sure whether C does so, but I believe that Perl does NOT
> promise that auto-increments will be executed in the "expected"
> left-to-right order. Thus, if a single expression includes more than
> one auto-increment working on the same variable, generally you can't
> be sure what Perl will do with it. As you found.
>
> Did this come up in a real-world situation, or were you specifically
> s ing to test the limits of Perl? In other words, what problem, if
> any, are you trying to solve?
I think it's academic Tom, and it's caught my interest!
The order of evaluation is immaterial, look:
$a = 3;
$b = 0;
$b += ++$a; # Now $a == 4, $b == 4
$b += $a++; # Now $a == 5, $b == 8
$a = 3;
$b = 0;
$b += $a++; # Now $a == 4, $b == 3
$b += ++$a; # Now $a == 5, $b == 8
so the final values of $a and $b are the same regardless and Perl is definitely
doing something wrongly in the single-line version. Although it's clearly not
a very important thing since it's managed to remain unfixed since at least
v5.6 if not before!
Cheers,
Rob
| |
| Taha Hafeez Siddiqi 2006-10-19, 6:56 pm |
| On Thu, 2006-10-19 at 15:20 +0200, Jenda Krynicky wrote:
> To: beginners@perl.org
> Date sent: Thu, 19 Oct 2006 13:55:45 +0200
> From: Norbert Preining <preining@logic.at>
> Copies to: Elisa Mori <morie@unisi.it>, preining@logic.at
> Subject: Evaluation of ++ different in C and perl?
>
>
> Anyone who uses something like that begs for problems.
> Just don't do that.
>
> Jenda
>
> ===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
> When it comes to wine, women and song, wizards are allowed
> to get drunk and croon as much as they like.
> -- Terry Pratchett in Sourcery
>
>
Hi Norbert,
Basically what Jenda said is an casual way of saying "it is undefined".
If you go through the C or C++ documentation, you will find these
expressions
as called "undefined"
Actually, the language keeps quit on the order of evaluation and the
implementation is free to do it the ways it wishes i.e.
in the expression
a() + b()
function a() or b() can be called in any order (a() then b() or b() then
a())
so if a() modifies some value that b() will be using, the result will be
undefined
as the order decides what the result will be...
I hope it helps
taha
| |
| DJ Stunks 2006-10-19, 6:56 pm |
| Norbert Preining wrote:
> Hi all!
> Maybe this has been answered before, but my searching didn't show up
> anything: The Perl Book says: Auto increment and decrement work as in C.
I don't know about The Perl Book, but your exact question is addressed
in the perldocs.
> So if I take this C program:
> #include <stdio.h>
> #include <stddef.h>
> int main() {
> int a;
> int b;
> a=3;
> b=(++a)+(a++);
> printf("b=%d\n",b);
> }
> it prints b=8.
>
> When I do the same in perl:
> $a = 3;
> $b = (++$a) + ($a++);
> print "b=$b\n";
>
> It prints b=9.
>
> I checked with a friend and Java behaves like C and prints 8.
>
> Can someone enlighten us by giving an interpretation of the above term?
Allow me to quote the docs directly:
[color=darkred]
OP> Auto-increment and Auto-decrement
OP> "++" and "--" work as in C. That is, if placed before a variable,
OP> they increment or decrement the variable by one before returning
OP> the value, and if placed after, increment or decrement after
OP> returning the value.
OP>
OP> $i = 0; $j = 0;
OP> print $i++; # prints 0
OP> print ++$j; # prints 1
OP>
OP> Note that just as in C, Perl doesn't define when the variable is
OP> incremented or decremented. You just know it will be done sometime
OP> before or after the value is returned. This also means that
OP> modifying a variable twice in the same statement will lead to
OP> undefined behaviour.
OP>
OP> Avoid statements like:
OP>
OP> $i = $i ++;
OP> print ++ $i + $i ++;
OP>
OP> Perl will not guarantee what the result of the above statements.
HTH,
-jp
| |
| nobull67@gmail.com 2006-10-19, 6:56 pm |
|
On Oct 19, 5:11 pm, Uri Guttman <u...@stemsystems.com> wrote:
> it is undefined behavior in most langs.
Absolutely, however, if purely as an academic exercise you wish to
understand what's really going on (in the current implementation) ...
http://birmingham.pm.org/talks/brian/ooe/Intro.xhtml
| |
| Tom Phoenix 2006-10-19, 6:56 pm |
| On 10/19/06, Norbert Preining <preining@logic.at> wrote:
> BUT: Even if we consider *both* ways of evaluation the expression tree,
> we arrive at 8:
There's more than both ways to do it.
I suspect that this is a result of an optimization that assumes that
no variable will appear at in multiple auto-increments within the same
expression. If there were a good reason to do write expressions like
that, I'd want it to be fixed; but I can't think of any.
Cheers!
--Tom Phoenix
Stonehenge Perl Training
| |
| Tom Phoenix 2006-10-19, 6:56 pm |
| On 10/19/06, Rob Dixon <rob.dixon@350.com> wrote:
> so the final values of $a and $b are the same regardless and Perl is definitely
> doing something wrongly in the single-line version.
I would argue that the programmer did something wrongly by abusing the
auto-increment. But don't let that stop you from filing a bug report,
if you wish.
If you file a bug report and the response is "Well, don't do that,
then", don't say you weren't warned. :-)
--Tom Phoenix
Stonehenge Perl Training
| |
| DJ Stunks 2006-10-19, 6:56 pm |
|
nobull67@gmail.com wrote:
> On Oct 19, 5:11 pm, Uri Guttman <u...@stemsystems.com> wrote:
>
>
> Absolutely, however, if purely as an academic exercise you wish to
> understand what's really going on (in the current implementation) ...
>
> http://birmingham.pm.org/talks/brian/ooe/Intro.xhtml
Good explanation :)
-jp
| |
| Norbert Preining 2006-10-19, 6:56 pm |
| Hi Tom!
On Don, 19 Okt 2006, Tom Phoenix wrote:
>
> I'm not sure whether C does so, but I believe that Perl does NOT
No, also C does not guarantee any predescribed order. It depends on the
compiler.
BUT: Even if we consider *both* ways of evaluation the expression tree,
we arrive at 8:
Lets take the following evaluation: Let
e1 (++$a)
e2 ($a++)
e3 e1 + e2
we evaluate first e1 and obtain for e1 the value 4 (as it is an
pre-increment), a is now also 4.
Then we evaluate e2: ($a++) which evaluates to 4, too, because this time
it is an post-increment.
Evaluation e3: 4+4 gives 8.
If we do the other ordering:
e1 ($a++)
e2 (++$a)
e3 e1 + e2
we evaluate first expression 1: $a++, which gives 3 (and a is 4 as it is
a post-increment). Then we evaluate e2: which gives 5 (and a is also 5),
so wie have 3 + 5 which is also 8.
I only see an explanation when the pre-increment *NOT*ALWAYS* returns
the value *pre increment.
OR: the expression tree is not actually evaluated in some sub-tree
order, but in some leave up order. Then we would have
e1 ++$a
e2 $a++
e3 (++$a)
e4 ($a++)
e5 e3 + e4
which would yield:
e1 4 pre increment, a=4
e2 4 a=5
e3 4
e4 5 it returns the current value of a
e5 9
(the above interpretation is very unclear, but it is the only way I can
see an explanation)
But this would be extremely counter-intuitive!!!
> Did this come up in a real-world situation, or were you specifically
> s ing to test the limits of Perl? In other words, what problem, if
> any, are you trying to solve?
Teaching Perl to students, and to get them to understand the difference
between pre and post increment.
Best wishes
Norbert
-------------------------------------------------------------------------------
Dr. Norbert Preining <preining@logic.at> Università di Siena
Debian Developer <preining@debian.org> Debian TeX Group
gpg DSA: 0x09C5B094 fp: 14DF 2E6C 0307 BE6D AD76 A9C0 D2BF 4AA3 09C5 B094
-------------------------------------------------------------------------------
Now it is such a bizarrely improbable coincidence that
anything so mindboggingly useful could have evolved purely
by chance that some thinkers have chosen to see it as the
final and clinching proof of the non-existence of God.
The argument goes something like this: `I refuse to prove
that I exist,' says God, `for proof denies faith, and
without faith I am nothing.'
The Babel fish is a dead giveaway, isn't
it? It could not have evolved by chance. It proves you
exist, and so therefore, by your own arguments, you don't.
QED.'
--- Douglas Adams, The Hitchhikers Guide to the Galaxy
| |
| lawrence@cluon.com 2006-10-19, 6:56 pm |
| > > Did this come up in a real-world situation, or were you specifically
>
> Teaching Perl to students, and to get them to understand the difference
> between pre and post increment.
>
So, I guess you have a much BETTER lesson to teach: Multiple
assigments to a variable between sequence-points (to borrow from C
terminology) can result in bizarre behavior and should be avoided.
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Lawrence Statton - lawrenabae@abaluon.abaom s/aba/c/g
Computer software consists of only two components: ones and
zeros, in roughly equal proportions. All that is required is to
sort them into the correct order.
| |
| Paul Johnson 2006-10-19, 6:56 pm |
| On Thu, Oct 19, 2006 at 09:56:58AM -0700, Tom Phoenix wrote:
> On 10/19/06, Rob Dixon <rob.dixon@350.com> wrote:
>
>
> I would argue that the programmer did something wrongly by abusing the
> auto-increment. But don't let that stop you from filing a bug report,
> if you wish.
>
> If you file a bug report and the response is "Well, don't do that,
> then", don't say you weren't warned. :-)
And that will be the response.
perlop says:
Note that just as in C, Perl doesn't define B<when> the variable is
incremented or decremented. You just know it will be done sometime
before or after the value is returned. This also means that
modifying a variable twice in the same statement will lead to
undefined behaviour. Avoid statements like:
$i = $i ++;
print ++ $i + $i ++;
Perl will not guarantee what the result of the above statements
is.
The key to this is what would be called sequence points and undefined
behaviour in C. Perl doesn't have the formal concepts of sequence
points or undefined behaviour, but in general you should assume it does.
The reasons for the observed behaviour are implementation dependent and
might change in future releases. Once you know what is happening you will
understand why you see the current results (of course), but the behaviour is
not obvious without that understanding.
Reread Lawrence Statton's replies - he knows what he's talking about.
--
Paul Johnson - paul@pjcj.net
http://www.pjcj.net
| |
| Dr.Ruud 2006-10-20, 3:58 am |
| Norbert Preining schreef:
> Dr.Ruud:
>
> Nup, this is not the solution:
Solution?
It showed that there is a bug. I already reported it.
--
Affijn, Ruud
"Gewoon is een tijger."
| |
| Paul Johnson 2006-10-20, 7:57 am |
| On Fri, Oct 20, 2006 at 10:56:09AM +0200, Dr.Ruud wrote:
> Norbert Preining schreef:
>
>
> Solution?
>
> It showed that there is a bug. I already reported it.
And I already replied ENOTABUG as promised ;-)
--
Paul Johnson - paul@pjcj.net
http://www.pjcj.net
| |
| Rob Dixon 2006-10-20, 7:57 am |
| Paul Johnson wrote:
>
> On Fri, Oct 20, 2006 at 10:56:09AM +0200, Dr.Ruud wrote:
>
>
> And I already replied ENOTABUG as promised ;-)
It's clear what the language should be doing in this situation and it isn't
doing it, so it's broken. It's only not a bug in the sense that it's documented
to be broken.
Rob
| |
| Dr.Ruud 2006-10-20, 7:57 am |
| Paul Johnson schreef:
> Dr.Ruud:
[color=darkred]
>
> And I already replied ENOTABUG as promised ;-)
Heheh, watch my wording: "there is a bug", not "this is a bug". :)
(And now it's up to me to make this non-DWIM-mery go away. Don't hold
your breath though.)
--
Affijn, Ruud
"Gewoon is een tijger."
| |
| Paul Johnson 2006-10-20, 7:57 am |
| On Fri, Oct 20, 2006 at 12:23:57PM +0100, Rob Dixon wrote:
> Paul Johnson wrote:
>
> It's clear what the language should be doing in this situation and it
> isn't doing it, so it's broken. It's only not a bug in the sense that
> it's documented to be broken.
I suppose this depends on whether you fall into the C camp or the Java
camp on this one. (Substitute your favourite language that either does
or does not define an order of evaluation.)
The primary reason that C and Perl leave this behaviour undefined is
for implementation efficiency. Now you may well cry that this reason is
bogus, as did the creators of Java, but it is so engrained in the
implementations of those languages that I don't think you are going to
have much luck trying to change it. You're welcome to try, of course,
if you are getting fed up of all those demons flying out of your nose.
To compensate for this perceived di vantage you get the advantage that
you will need to make your code simpler and easier to understand ;-)
--
Paul Johnson - paul@pjcj.net
http://www.pjcj.net
| |
| lawrence@cluon.com 2006-10-20, 7:57 am |
| > >> It showed that there is a bug. I already reported it.
>
> It's clear what the language should be doing in this situation and it isn't
> doing it, so it's broken. It's only not a bug in the sense that it's documented
> to be broken.
>
> Rob
No, it is not "clear" what the language "should" be doing.
*EXACTLY AS IN C* multiple assignments within an expression is
UNDEFINED behavior.
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Lawrence Statton - lawrenabae@abaluon.abaom s/aba/c/g
Computer software consists of only two components: ones and
zeros, in roughly equal proportions. All that is required is to
sort them into the correct order.
| |
| Paul Johnson 2006-10-20, 7:57 am |
| On Fri, Oct 20, 2006 at 08:11:36AM -0500, lawrence@cluon.com wrote:
> Computer software consists of only two components: ones and
> zeros, in roughly equal proportions. All that is required is to
> sort them into the correct order.
Andrew Preview: You're playing all the wrong notes.
Eric Morecambe: I am playing all the right notes... but not necessarily
in the right order.
But, without thinking too hard about it, I would have expected quite a
few more zeros than ones in the average program.
Hmmm. Is it the w end yet?
--
Paul Johnson - paul@pjcj.net
http://www.pjcj.net
| |
| Derek B. Smith 2006-10-20, 6:56 pm |
| --- Paul Johnson <paul@pjcj.net> wrote:
> On Fri, Oct 20, 2006 at 08:11:36AM -0500,
> lawrence@cluon.com wrote:
>
> components: ones and
> required is to
>
> Andrew Preview: You're playing all the wrong notes.
> Eric Morecambe: I am playing all the right notes...
> but not necessarily
> in the right order.
>
> But, without thinking too hard about it, I would
> have expected quite a
> few more zeros than ones in the average program.
>
> Hmmm. Is it the w end yet?
>
> --
> Paul Johnson - paul@pjcj.net
I am no Perl guru, but like to think of my self as
good at programming and enjoy it, but I am happy with
the clarity of perlop:
Note that just as in C, Perl doesn't define when the
variable is incre-
mented or decremented. You just know it will be done
sometime before or
after the value is returned. This also means that
modifying a variable
twice in the same statement will lead to undefined
behaviour. Avoid
statements like:
$i = $i ++;
print ++ $i + $i ++;
So since its documented and not recommended and
considered bad coding I would say its not a bug.
However since the only thing higher that ++ or -- is
left terms and list operators (leftward)
left ->
and we tested () which had no result we wanted to see,
I guess we have to ask ourselves again what defines a
bug?
________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
| |
| Rob Dixon 2006-10-20, 6:56 pm |
| lawrence@cluon.com wrote:
>
>
> No, it is not "clear" what the language "should" be doing.
Of course it is. The operands of addition are evaluated from left to right; the
return value of a pre-increment is the value of the operand after it is
incremented; the return value of a post-increment is the value of the operand
before it is incremented; and pre- and post-increments have a higher priority
than additions. $a = 3; ++$a + $a++ _should_:
- increment $a to 4 and return 4
- increment $a to 5 and return 4
- add 4 and 4 and return 8
and it doesn't. It's broken.
> *EXACTLY AS IN C* multiple assignments within an expression is
> UNDEFINED behavior.
Yes. It's documented to be broken.
Rob
| |
| Rob Dixon 2006-10-20, 6:56 pm |
| Paul Johnson wrote:
> On Fri, Oct 20, 2006 at 12:23:57PM +0100, Rob Dixon wrote:
>
>
> I suppose this depends on whether you fall into the C camp or the Java
> camp on this one. (Substitute your favourite language that either does
> or does not define an order of evaluation.)
But it's not a problem with the order of evaluation Paul. Whether you think
$b = ++$a + $a++
means
$b = ++$a;
$b += $a++;
or
$b = $a++;
$b += ++$a;
the answer comes out the same, and different from what Perl makes of it. Perl is
turning it into
$b = (++$a, $a++, $a + $a)
So an error has been optimised in, and what is worse is that it does it without
a squeak of a warning; this in a language that will whine if you use an array
slice when it thinks you don't mean one.
Rob
| |
| Tom Phoenix 2006-10-20, 6:56 pm |
| On 10/20/06, Rob Dixon <rob.dixon@350.com> wrote:
> So an error has been optimised in, and what is worse is that it does it without
> a squeak of a warning;
If you want to issue a warning to the programmer who intentionally
causes this to happen, submit a patch. But the documentation is
warning enough, since code like this doesn't happen by accident.
--Tom Phoenix
Stonehenge Perl Training
| |
| Uri Guttman 2006-10-20, 6:56 pm |
| >>>>> "RD" == Rob Dixon <rob.dixon@350.com> writes:
RD> and it doesn't. It's broken.
[color=darkred]
RD> Yes. It's documented to be broken.
you can keep saying that but it won't change the reality. it is
documented to be undefined behavior. it won't be changed because of your
views. so let it go already. even if it had defined behavior it is BAD
coding to do multiple side effects in one statement. the whole concept
of statements is to make side effects work correctly (a known state
exists between statements) so bypassing them by doing this is just
wrong.
WRONG! WRONG! WRONG! WRONG!
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
| |
| JCScott 2006-10-22, 8:10 am |
| quote: Originally posted by Norbert Preining
[B]The Perl Book says: Auto increment and decrement work as in C.
So if I take this C program:
#include <stdio.h>
#include <stddef.h>
int main() {
int a;
int b;
a=3;
b=(++a)+(a++);
printf("b=%d\n",b);
}
it prints b=8.
… or 42. Or it dumps core. Or it makes demons fly out of your nose. How many compilers have you tried this on?
Try
code: #include <stdio.h>
int main()
{
int a, b, c;
a = b = 3;
c = (++a) + (b++);
printf("c=%d\n", c);
}
instead.
quote: When I do the same in perl:
Same issue: undefined order of operations.
quote: Originally posted by Rob Dixon
Whether you think
$b = ++$a + $a++
means
$b = ++$a;
$b += $a++;
or
$b = $a++;
$b += ++$a;
the answer comes out the same
Sure; but what about translating
code: b = ++a + a++;
as:
code: int c, p, aa[2];
pipe(fd);
switch(p = rfork(OPTIONS TO SHARE MEMORY)){
case 0:
c = a + 1;
a = c;
aa[0] = a;
exit(0);
default:
aa[1] = a;
c = a + 1; /* this CPU doesn’t have an increment operation */
a = c;
}
waitpid(p); /* or whatever the syntax is */
b = aa[0] + aa[1];
See that pretty race condition?
Artificial? Sure it is -- except if you're on an Itanium system with cpu-level parallelization. The laguage manual says “don’t do that”, so the compliler is allowed to assume you won’t and optimize accordingly.
JCS | |
| JCScott 2006-10-22, 8:13 am |
| Oh, and ignore that “pipe(fd);” line; I was trying to be even more evil in my traslation but reconsidered, and I forgot to take that line out.
JCS | |
|
| quote: Originally posted by Norbert Preining
.....
b=(++a)+(a++);
.....
Can someone enlighten us by giving an interpretation of the above term?
Thanks a lot and all the best
Norbert
-------------------------------------------------------------------------
It's very simple. C does not specify in what order the expressions will be evaluated. If the (++a) is evaluated first, then you wind up with 8. If the compiler decides to evaluate the (a++) first, then you wind up with 9. You could get either answer depending on which C compiler you used, or maybe different results on different compiles. Most textbooks explain this point. Your Perl run happened to pick the evaluation order different from your C compile. They could as easily have swapped results, or both had the same. In general, the result is unpredictable. | |
| Rob Dixon 2006-10-23, 7:57 am |
| lawrence@cluon.com writes:
>
> No, it is not "clear" what the language "should" be doing.
Of course it is. The operands of addition are evaluated from left to right;
the
return value of a pre-increment is the value of the operand after it is
incremented; the return value of a post-increment is the value of the
operand
before it is incremented; and pre- and post-increments have a higher
priority
than additions. $a = 3; ++$a + $a++ _should_:
- increment $a to 4 and return 4
- increment $a to 5 and return 4
- add 4 and 4 and return 8
and it doesn't. It's broken.
> *EXACTLY AS IN C* multiple assignments within an expression is
> UNDEFINED behavior.
Yes. It's documented to be broken.
Rob
| |
| Rob Dixon 2006-10-23, 9:57 pm |
| Jay Savage wrote:
> On 10/20/06, Rob Dixon <rob.dixon@350.com> wrote:
>
> How is it clear what the language should be doing? Repeat after me:
> addition is a commutative.
Addition is a commutative.
> The order of addition by definition does not matter, and any attempt to make
> it matter should absolutely return an undefined behavior. Why should Perl
> guarantee that it will read the operands of '+' from left to right? As far as
> I'm concerned, the Perl/C people have this one right. Given
>
> $x = 3;
> $y = ++$x + $x++;
>
> It seems to me that the flow (remembering that addition is
> commutative) could be optimized to
>
> $y = $x++; # $y = 3, postincrement, $x=4
> $y += ++$x; # preincrement, $x = 5, $y = 9
>
> That makes perfect sense to me. The optimizer sees that it needs an
> unincremented $x, inlines the '3', and then gets on witth the
> increments. Because, let me say it again, addition is commutative.
A lot of the rest of your argument breaks down here Jay, because 3 + 5 == 8, not
9. And whichever increment operator is executed first the result should be
either 3 + 5 or 4 + 4, but instead Perl provides 9, as if both were preincrement
operators.
I admit that the documentation is silent on which side of the addition operator
is evaluated first, but it is implied strongly - see later. And the fact that
addition is commutative is also irrelevant, as both arguments must be evaluated
before the addition is applied whether it is an addition or, say, a subtraction,
which is non-commutative.
> If you want to perform addition where the order of execution does
> matter, it's up to you to ensure the order.
>
> $y = (0 + ++$x) + $x++; # gets 8
> $y = (++$x + 0) + $x++; # gets 8
> $y = ++$x + (0 + $x++); # gets 9
> $y = ++$x + ($x++ + 0); # gets 9
>
> for instance, seem to yield the expected results. I'd still try to split the
> increments into separate statements if possible, though, because I don't think
> that behavior is guaranteed.
Now /here/ the behaviour /is/ guaranteed, even without the parentheses. perlop
says:
*Operator associativity* defines what happens if a sequence of the same
operators is used one after another: whether the evaluator will evaluate
the left operations first or the right. For example, in "8 - 4 - 2",
subtraction is left associative so Perl evaluates the expression left to
right. "8 - 4" is evaluated first making the expression "4 - 2 == 2" and
not "8 - 2 == 6".
and addition is also left-associative to Perl, so
$y = 0 + ++$x + $x++
unambiguously means
$y = (0 + ++$x) + $x++;
and (here is what I meant above by the order being strongly implied) it would
very perverse of Perl to do it this way round but to evaluate the right-hand
half of
++$x + $x++
before the left. (And anyway, as I've said already, the answer still isn't 9!)
> The current optimizer seems to perform the variable substitution when the
> parens are evaluated, but I don't see why that couldn't break at some point;
> it's still non-commutative and therefore undefined.
In this case the evaluator is substituting /operator/ values, not variables.
It's helpful to think of operators as just functions with a different syntax,
and if I write the equivalent:
sub ppx { $_[0] += 1; return $_[0]; }
sub xpp { my $t = $_[0]; $_[0] += 1; return $t; }
my $a = 3;
my $b = ppx($a) + xpp($a);
print $b, "\n";
then I get my '8' as I expected (even if you reverse the operands of the
addition). The built-in operators should behave the same way, or at least bleat
at you and say that they're not going to.
> Perl is good about DWIM, but don't expect it to read your mind and figure out
> which mathematical properties you'd like to suspend today. If you want to
> re-write the rules of logic to suit your fancy, it's up to you to
> rewirte the optimizer to suit your fancy, too.
No mathematical property suspension or logic rule rewriting required. 3+5 == 5+3
== 4+4 == 8, not 9
> At least that's my $.02.
>
> I'd also recommend against using the reserved variables $a and $b in
> examples.
Thay can be tricky things, but to be honest I'm inclined to think that the magic
sort variables should be something other than $a and $b, or at least they should
be implicitly localized inside a sort block. But that's another thing...
> That in itself should be a warning that the problem is with the implementor,
> not the implementation.
Not sure what you mean. Presumably that it's the Perl programmer's fault and not
the Perl implementors'? I don't see how $a and $b have anything to do with that,
and I think using them is absolutely fine as long as they're in a program that's
short enough for it to be blatantly obvious that there are no calls to sort(),
which this one was. But then I also think that using $& is also fine as long as
your program runs fast enough for you, so maybe it's just me :)
By the way, for further thought you might like to consider the simpler
my $a;
my $b = ($a = 1) + ($a = 2);
which clears away any confusion over order of evaluation.
Cheers,
Rob
| |
| oroszib@vpg.sulinet.hu 2006-10-23, 9:57 pm |
| In the C language what the debate is about is clearly: UNDEFINED.
Java works deliberately DIFFERENTLY, it enforces a predictable sequence.
I think in Perl, the outcome is also UNDEFINED (as Mr. Jay already said).
I presume the Perl language acts here just as C. It is pointless to
argue about order and whatsoever, unless you know the given language
STANDARD back and forth. It is a language specific issue, so don't come
with saying
"++x increments, then returns, x++ returns "then" increments, so the
outcome is xyz, regardless of order blah, blah..."
until you KNOW for SURE what the language says about the issue
(currently: referencing an incremented variable in the same expression).
I strongly suggest everyone to read this article (although it is for C,
I think the same applies to Perl):
http://c-faq.com/expr/evalorder2.html
Other nice questions:
http://c-faq.com/expr/
For a little fun, I wrote a little C program and a Perl equivalent.
#include <stdio.h>
int main()
{
int x;
x = 0; printf("%d\n",++x + ++x);
x = 0; printf("%d\n",x++ + x++);
x = 0; printf("%d\n",++x + x++);
x = 0; printf("%d\n",x++ + ++x);
return 0;
}
gcc -Wall -o test.exe test.c
test.c: In function `main':
test.c:6: warning: operation on `x' may be undefined
test.c:7: warning: operation on `x' may be undefined
test.c:8: warning: operation on `x' may be undefined
test.c:9: warning: operation on `x' may be undefined
test.exe
4
0
2
2
The result is the same with MSVC 2003 compiler.
And in Perl:
use strict;
my $x;
$x = 0; printf("%d\n", ++$x + ++$x);
$x = 0; printf("%d\n", $x++ + $x++);
$x = 0; printf("%d\n", ++$x + $x++);
$x = 0; printf("%d\n", $x++ + ++$x);
perl test.pl
4
1
3
2
--
Greets,
B.
P.S.: As to the C program, that the original author posted: the outcome
of that is also UNDEFINED. It was mere luck or chance, that the result
was 8. GCC issues a warning for that too.
|
|
|
|
|