in reply to Re: An obscure side effect?
in thread An obscure side effect?

Interesting. I did think about the order of execution thing, and whether that might be the cause, but then I tried this.

#! perl -slw use strict; sub swab{ substr( $_[0], $_[1], 1 ) ^= substr( $_[0], $_[2], 1 ) ^= substr( $_[0], $_[1], 1 ) ^= substr( $_[0], $_[2], 1 ) } my $s ='AB'; swab( $s, 0, 1 ); print "'$s'"; my $t ='AB'; swab( $t, 0, 1 ); print "'$t'"; eval q[ sub swab{ substr( $_[0], $_[1], 1 ) ^= substr( $_[0], $_[2], 1 ) ^= substr( $_[0], $_[1], 1 ) ^= substr( $_[0], $_[2], 1 ) } ]; my $u = 'AB'; swab( $u, 0, 1 ); print "'$u'"; swab( $u, 0, 1 ); print "'$u'"; __END__ P:\test>junk 'BA' ' A' Subroutine swab redefined at (eval 1) line 2. 'BA' ' B'

By redefining swab(), the behaviour goes back to the original, expected result for the first time I call it, with a second and any subsequent calls to the redefined swab() producing erroneous effects.

Then I tried this

#! perl -slw use strict; sub swab1{ substr( $_[0], $_[1], 1 ) ^= substr( $_[0], $_[2], 1 ) ^= substr( $_[0], $_[1], 1 ) ^= substr( $_[0], $_[2], 1 ) } sub swab2{ substr( $_[0], $_[1], 1 ) ^= substr( $_[0], $_[2], 1 ) ^= substr( $_[0], $_[1], 1 ) ^= substr( $_[0], $_[2], 1 ) } my $s ='AB'; swab1( $s, 0, 1 ); print "'$s'"; swab2( $s, 0, 1 ); print "'$s'"; my $u = 'AB'; swab1( $u, 0, 1 ); print "'$u'"; swab2( $u, 0, 1 ); print "'$u'"; __END__ P:\test>junk 'BA' 'AB' ' A' ' '

This shows that both instances of the routine produce the correct result the first time they are called, but then erroneous effects the second time.

This suggests to me that there is an uninitialised piece of memory being used somewhere that was probably initialised to \0 by the malloc or memset that allocated the larger pool of memory from which it was suballocated, but when the routine is called a second time, the same piece of memory is being reallocated from the same pool, but now has whatever last value it contained. Perhaps it is just a C auto that is being allocated on the stack and happens to have a zero in it the first time it is called, but retains the last value it had the next time it gets used?


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
If I understand your problem, I can solve it! Of course, the same can be said for you.

Replies are listed 'Best First'.
Re: Re: Re: An obscure side effect?
by sgifford (Prior) on Aug 04, 2003 at 06:25 UTC
    I haven't been able to find any good, solid information about Perl's order of execution for assignment and operand evaluation. If it is the case that the order is undefined in swab, then if Perl wanted to evaluate it one way on Wednesdays and another on Thursdays, unless it was a leap year, that would be perfectly valid...

      Whilst the order maybe unspecified and potentially vary from build to build, I would expect that the same line of code to evaluate in a consistant fashion within a given build, especially within a given run.

      Unless of course it is littered with :)

      /* Teach them not to bracket enough {evil grin} */ switch ( int( rand()*varients ) ) { case 0: {...}; case 1: {...}; ....; }

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      If I understand your problem, I can solve it! Of course, the same can be said for you.

        That's what I would expect, too, but if the order is undefined, we're not guaranteed to get what we expect.

        For example, say that while a sub is running, it becomes apparent to Perl that the way it ordered things last time wasn't optimal (maybe the sub rarely uses its second argument, so evaluation of this argument should be deferred until it's actually used). Although unlikely, it would be legal to re-order anything whose order was undefined.

        This is certainly bizarre behavior, and may well be a bug, but I've not seen mention of, or found, any solid documentation about whether the order of execution for these assignment and xor operators are defined or not, and if they are defined what the order is supposed to be.