Hi Monks

This behaviour is there with C/C++ "printf" also. We need to know how the "print" statement (see coments below ) is handling variables & its data. Our code in question is

my $x = 0; print $x, $x++; # Print 10??

All the arguments passed to the "print" is kept in a stack! print will push arguments from right-to-left into the stack. Inthe above case value of $x goes into stack (corresponding to $x++).

After the first "push", $x is incremented and on second "push" new value of $x is pushed. Then it start poping to print. For sure it will pop 1 first and then 0. So it will print 10. A program to demo this can be

#!/usr/bin/perl use strict; my @PRINT_STACK; my $x = 0; push @PRINT_STACK, $x++; print "PRINT_STACK => ( ",@PRINT_STACK, " )\n"; push @PRINT_STACK, $x; print "PRINT_STACK =>( ",join(", ",@PRINT_STACK)," )\n"; print pop @PRINT_STACK; print pop @PRINT_STACK; exit();

Again funny facts :)

my $x = 0; print $x,$x, $x++; # Print 110??

This will print 110 for sure, because the value of $x is NOT changed after first push.

Then what would be

my $x = 0; print $x,$x++, $x++; # Print 210??

In case of "C" it will print 210 as expected. but the output you will get in perl is 201. If I make a table with more $x++ in print, it will be as follows (assuming that initial value of $x is 0 ).

Print orderO/P in CO/P in Perl
$x00
$x,$x++1010
$x,$x,$x++110110
$x,$x++,$x++210201
$x,$x++,$x++,$x++32103012
$x,$x++,$x++,$x++,$x++4321040123
$x,$x++,$x++,$x++,$x++,$x++543210501234

"C" is working as I explained above. Why Perl is behaving differently when we have "$x,$x++,$x++" ? Answer is again stacks.

when there are more than one expressions in same statement, perl uses another stack for evaluating them. ie, it wll push 0 to stack first. Then increments $x to 1. Then again it pushes 1 to stack and increments it to 2. Now all operations are over. Now Perl with pop contents of the operation stack and push to print stack. Then push the last $x. So it will print "201" for

print $x,$x++,$x++

Following program will demonstrate the entire thing :)

#!/usr/bin/perl use strict; my @PRINT_STACK; my @OP_STACK; my $x = 0; my $temp; #print $x,$x++,$x++; push @OP_STACK, $x++; # push the l +ast $x++ to the operator stack (pushes 0) print "OP_STACK => ( ",@OP_STACK, " )\n"; push @OP_STACK, $x++; # push the n +ext $x++ operator to the operator stack (pushes 1) print "OP_STACK => ( ",join(", ",@OP_STACK)," )\n"; # All Operations are over $temp = pop @OP_STACK; #pop The ope +rator stack and push it to print stack (pops 1) push @PRINT_STACK, $temp; # pushes 1 print "PRINT_STACK => ( ",join(", ",@PRINT_STACK)," )\n"; $temp = pop @OP_STACK; #pop The ope +rator stack and push it to print stack (pops 0) push @PRINT_STACK, $temp; #pushes 0 print "PRINT_STACK => ( ",join(", ",@PRINT_STACK)," )\n"; push @PRINT_STACK, $x; # push the f +irst $x to the operator stack (pushes 2) print "PRINT_STACK => ( ",join(", ",@PRINT_STACK)," )\n"; print pop @PRINT_STACK; print pop @PRINT_STACK; print pop @PRINT_STACK; exit();

Isn't this a nice hack for obfuscation ?

Comments

Cheers!

--VC

UPDATE : I am not sure about all C compilers. I got above behavior with "gcc on FC6 & Turbo C on Windows XP". Also for Perl I tested with "Active Perl On Windows XP & Perl on FC6". I was NOT trying to say Perl & C will behave alike, but I was trying to say that this IS there with most of the implementation of C (gcc on FC6 and turbo C on Windows XP) & Perl (Active Perl On Win XP and perl on FC6). SORRY if misleading.


In reply to Re: print behavior by atemon
in thread print behavior by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.