Re: FAQ 4.47 How do I handle circular lists?



On 2008-05-14 09:09, sheinrich@xxxxxxxxxxx <sheinrich@xxxxxxxxxxx> wrote:
On May 13, 3:11 pm, "John W. Krahn" <some...@xxxxxxxxxxx> wrote:
sheinr...@xxxxxxxxxxx wrote:
$index = ++$index % $asize;

perldoc perlop

[ SNIP ]

Note that just as in C, Perl doesn’t define 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.

So don't do that. Do this instead:

$index = ( $index + 1 ) % $asize;


"You just know it will be done sometime before or after the value is
returned."

I've been reading that as 'sometime before' in case of a preincrement,
'after' for a postincrement.

In which case my
$index = ++$index % $asize;

looks fairly safe.

It may not be.

IMHO the expression above can result in an error only, if the
increment is first computed and returned and is assigned to $index
only after the modulo operation or even after the explicit assignment.

Right. The compiler could produce something like:

$tmp1 = $index + 1
$tmp2 = $tmp1 % $asize
$index = $tmp2
$index = $tmp1

You may be right in that this can really happen. But then it's a very
strange behaviour indeed.

Not that strange for compilers which produce code for real CPUs (which
often have very strange timing requirements). I wouldn't really expect
it from a simple bytecode-generating compiler like perl's.


The warning that the execution order is undefined comes from C. But in C
this is a consequence of the concept of "sequence points". The language
defines certain points (e.g., the end of each statement, each function
call, etc.) where each previous operation must be finished and no
subsequent operation must have begun. between two sequence points the
compiler can reorder operations at will. There are two rules about
modifying values:

1) You can modify an object[1] only once between two sequence points
2) If you modify an object, you can only read it to compute the new
value.

But Perl doesn't have the concept of sequence points, and there is no
general prohibition agains modifying the same object twice in a
statement, just against using the increment and decrement operators.
That does stand out as an odd exception. IMHO Perl should either define
an execution order (which could be a partial order) or adopt a more
generic concept like that of C.


I've been using the autoincrement out of habit and for performance
considerations

Surprisingly,

$index = ++$index % $asize;

is really about 40 % faster than

$index = ( $index + 1 ) % $asize;

I had not expected this. Apparently creating a constant IV is a
relatively expensive operation (well, it takes about 36 nanoseconds on
my PC, so "relatively expensive" is, er, relative).

hp

.



Relevant Pages

  • Re: post increment or pre increment?
    ... $ perl bla.pl ... old value before the increment or the new value after the increment? ... Pre-increment is semantically simpler. ... On my system, for this simple loop, all three variants are the same ...
    (comp.lang.perl.misc)
  • Re: modify PVA.pl (z/OS and perl-5.8.6)
    ... This contains a sequence of property aliases ('ea' for EastAsianWidth, 'jt' for JoiningType and so on) and their corresponding values. ... I changed the order of propertynames in PVA_abbr_map, but perl -d still continues to follow the original sequence of property names and exits before 'ea' is used. ... I tried to modify PVA.pl manually on the linux box to to see if perl ran with this new sequence, so that the 'ea' case would be picked up before perl -d had a chance to exit. ...
    (perl.beginners)
  • Re: strange side-effect (bug?) in Net::SMTP
    ... Ian D. wrote: ... > believe a subroutine should be modifying $_, ... would preserve the value of $_ and any other globals it ... This is perl, v5.8.0 built for MSWin32-x86-multi-thread ...
    (comp.lang.perl.misc)
  • Re: FAQ 5.2 (Was: inserting lines)
    ... I recently complained about the lack of alternate approaches to the FAQ ... "How do I change one line in a file/delete a line in a file/insert a ... Perl is not a text editor. ... punch cards--computers usually see the text file as a sequence of bytes. ...
    (comp.lang.perl.misc)
  • Re: Removing sequence tag from SOAP WSDL Schema -- help please
    ... "Marvin Smit" wrote: ... > used by a perl implementation, which uses hashes and therefore cannot ... > maintain a sequence?" ... just change the sequence information. ...
    (microsoft.public.dotnet.framework.webservices)