in reply to Re^10: Setting signal handlers considered unsafe?
in thread Setting signal handlers considered unsafe?

In short, "don't do that". But if you're interested in the internal details, read on.

Values in Perl are stored in a struct call "SV" (or a derivative thereof). SVs aren't copied around. Pointers to SVs are. That results in "pass by reference" being the default model for every operator, function and sub. This creates interesting side-effects as seen in the following:

>perl -le"$x=3; print($x+0, $x, ++$x, $x, $x++, $x, $x+0);" 3555455

$x and ++$x place a pointer to $x's SV on the stack. $x+0 (and "$x" for strings) creates a new SV, so it's no affected by later changes to $x. Similarly, $x++ creates a new SV containing a copy of what $x was at the time of the increment.

Equivalent code in C++:

#include <stdio.h> void print(const int &g, const int &f, const int &e, const int &d, con +st int &c, const int &b, const int &a) { printf("%d%d%d%d%d%d%d\n", a, b, c, d, e, f, g); } int main() { int x = 3; print(0+x, x, x++, x, ++x, x, 0+x); // 5 5 4 5 5 5 3 return 0; }

(++x and 0+x produce constants in C++, but not in Perl.)

Replies are listed 'Best First'.
Re^12: Setting signal handlers considered unsafe? (OT: C++)
by gwadej (Chaplain) on Nov 11, 2008 at 21:14 UTC

    Of course, you should never do that in C++. The standard specifically states that modifying a variable more than once in the same statement results in either undefined or implementation defined behavior (depending on what is actually being done). In you case, it's implementation defined, because there is no way to know the order of evaluation of the arguments. You also don't know when the post-increment happens, except that it will occur before the subroutine actually starts.

    And technically, 0+x and ++x return r-values, not constants.

    Sorry about that. I'm a recovering C++ programmer.<grin/>

    G. Wade

      The point was to show what Perl does. I specifically mentioned the result was specific to my compiler.

      The standard specifically states that modifying a variable more than once in the same statement results in either undefined or implementation defined behavior (depending on what is actually being done).

      I believe foo(x++, x) is also undefined even though it only modifies the variable once.

      Basically, the same thing applies to Perl. While the order is predictable, relying on it is dangerous. I've seen the following a fair bit, though, which modifies and uses @_:

      sub foo { shift->bar(@_) }