Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Autoincrement operator precedence difference between C and Perl

by Mbk (Novice)
on Oct 09, 2007 at 06:51 UTC ( [id://643629]=perlquestion: print w/replies, xml ) Need Help??

Mbk has asked for the wisdom of the Perl Monks concerning the following question:

Hi All, I find some difference in auto increment operator precedence between C and Perl. As almost say that for Perl, the operators derived from C has the same precedence, this is somewhat different. Here is the sample code: Perl:
#!/usr/local/bin/perl -W $i = 2; $j = 10; $k = $i++ - $i++; print $k,"\n"; $i = 2; $j = 10; $k = ++$i - ++$i; print $k,"\n"; $i = 2; $j = 10; $k = $i++ + $i++; print $k,"\n"; $i = 2; $j = 10; $k = ++$i + ++$i; print $k,"\n"; which outputs: -1 0 5 8
and the equivalent C program:
#include <stdio.h> main() { int i,j,k; i = 2; j = 10; k = i++ - i++; printf("i=%d, j = %d, k = %d\n",i,j,k); i = 2; j = 10; k = ++i - ++i; printf("i=%d, j = %d, k = %d\n",i,j,k); i = 2; j = 10; k = i++ + i++; printf("i=%d, j = %d, k = %d\n",i,j,k); i = 2; j = 10; k = ++i + ++i; printf("i=%d, j = %d, k = %d\n",i,j,k); } which outputs: k = 0 k = 0 k = 4 k = 8
as you can observe the difference in outputs. Could anyone help me explaining whats happening here . why is the output different different especially with post-increment operator? Thanks,

Replies are listed 'Best First'.
Re: Autoincrement operator precedence difference between C and Perl
by ikegami (Patriarch) on Oct 09, 2007 at 07:00 UTC

    It's not a question of precedence, it's a question of operand evaluation order. For example, precedence dictates the multiplications will occur before the sum in 2*foo()+4*bar(), but it doesn't control the order in which foo() is called in relation to bar().

    Operand evaluation order is not defined in either language. Although I'm pretty sure you'll always get the same result in Perl5, you shouldn't rely on it. As for C, it's known to vary between compilers, between platforms and/or due to optimizations. Despite your claim, your snippet is not representative of C.

    Don't use and modify the same variable in the same statement.

Re: Autoincrement operator precedence difference between C and Perl
by Corion (Patriarch) on Oct 09, 2007 at 07:01 UTC

    This is less a Perl FAQ than a C FAQ. Even under C, the evaluation order of expressions is undefined and what you claim as "C" varies between compilers and optimization settings. Google for C FAQ preincrement.

      not only the order isn't defined but the result too.
      the code (a=B)*c/(a=C) in C not only means that you can't know if a will be B or C, but it can be something else (suppose the code run on a 16 bit host and a is 32 bit...)

      Oha

Re: Autoincrement operator precedence difference between C and Perl
by GrandFather (Saint) on Oct 09, 2007 at 07:06 UTC

    This is not a precedence issue, but an evaluation order issue. It is also not a difference between C and Perl, but a "by design" language specification issue that the evaluation order is not specified by either language. It is the same issue that means that the evaluation order of parameters passed to a sub is not specified.

    The language specifications are not specific about the evaluation order in such cases to allow compiler/interpreter writers freedom to evaluate such things in a way that best suits their code generators or optimizers.

    It is very likely that different C compilers will generate code that produces different results than you have seen. It is even possible that the same compiler will generate different answers when different compiler options are used.

    The bottom line is, don't use expressions or parameter lists where execution results are order dependent such as the examples given, or by calling subs that have side effects.


    Perl is environmentally friendly - it saves trees
Re: Autoincrement operator precedence difference between C and Perl
by shmem (Chancellor) on Oct 09, 2007 at 07:10 UTC
    See also this highly inflammatory thread: Quantum Weirdness and the Increment Operator

    update: and it is not autoincrement - you have that in database columns. It's pre-increment and post-increment proper.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Autoincrement operator precedence difference between C and Perl
by blokhead (Monsignor) on Oct 09, 2007 at 13:12 UTC
    I'm surprised everyone is attributing the weird results to the order in which Perl operators evaluate their arguments. Perl doesn't have a weird evaluation order. It does things left-to-right as you would expect. Even if it did, it wouldn't sufficiently describe the outputs above. The order in which arguments are evaluated is not specified as a feature, sure, but it's not like Perl is trying to be smart and do things in different orders each time. It reserves the right to do so, but as far as I know it does not. Also, I do not think it splits up the atomic operations $i++ or ++$i into smaller bits, as the C optimizer might be doing, but I don't know how to check for sure. My hunch is because the increment operator is "magic" while +=1 is not.

    I can't speak to what happens in C. But the real weirdness in Perl comes from the fact that the pre-increment operator returns an alias to $i (post-increment returns a plain old value). So in some of these examples, Perl evaluates the first ++$i, which returns an alias. The second increment operator changes $i. Because the first value is an alias to $i, its value also gets changed in this step before the addition operator acts on it. That is why ++$i + ++$i returns a value that is 4 greater than $i+$i: both increment operations increase both operands.

    Under this interpretation and left-to-right evaluation, you can fully describe the behavior of all of these expressions.

    blokhead

      While your observations are most probably correct, it stands as a fact that evaluation order of multiple pre/post-increments in one statement isn't explicitly defined in Perl 5, I guess on purpose. It is an artifact of the implementation of Perl - it is not in the language specs afaik - so you shouldn't rely on it, even if all perl 5 binaries we know of stack execution in the way you describe.

      And that is more than saying "while you can use multiple pre/post-increments in a single statement, it is bad practice and should be avoided" - it is saying "it's not defined. Don't".

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Autoincrement operator precedence difference between C and Perl
by Mbk (Novice) on Oct 09, 2007 at 08:30 UTC
    Thanks a lot Friends for your information.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://643629]
Approved by GrandFather
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2024-04-20 02:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found