On Wed, 19 Nov 2003, Chris Nandor wrote:

> At 10:59 -0500 2003.11.19, Dan Sugalski wrote:
> >On Wed, 19 Nov 2003, Chris Nandor wrote:
> >
> >> $ perl -le '$^E = -1728; print $^E+0 for 0,1; print $!+0 for 0,1'
> >> -1728
> >> 22
> >> 22
> >> 22
> >
> >Given that on Unix systems $^E and $! are identical, and that $! is
> >directly tied to errno, this certainly isn't surprising. Anything that
> >afects errno (like, say, IO) may then affect $! and $^E identically.(And
> >$!/$^E non-indentically on systems where they're separate)
> >
> >Basically you're using a variable that can be affected by external things
> >in a way that pretty much guarantees that external things will be
> >happening. That it changes isn't much of a surprise. ($!/$^E may get
> >modified by some signal handlers too, depending on what you do, so there's
> >not even any guarantee that "$^E = 42; $^E++;" will end up with $^E set to
> >43.
>
> It should not change its value merely by accessing its value.  It's never
> done that in previous versions of perl, and shouldn't do it now.

It's not the access. It's the print. Print may trigger a call into the C
runtime library, which may result in errno changing, which, since errno is
directly tied into $! and $^E, means that $! and $^E may change. The
degenerate example I gave, with $^E not even holding its value across
statements, is a rare but not impossible possibility -- if a signal hit in
there and the signal handler did something that affected errno then $^E
would change externally.

> If you're saying that the value of $! changing after $^E changes is not
> surprising, yes, I agree.  But the value of $^E changing is very
> surprising, and wrong.

Not wrong. Your assumptions about what's going on just turn out not to be
correct. $^E and $! are tied to an external data cell (in this case the
same cell) and while changes to $^E/$! will change that cell, changes to
that cell from external code will change $^E/$!.

Ultimately my bet is that Apple made a change in the C RTL that made errno
get twiddled more than it used to be, which is perfectly reasonable.
errno, and therefore $!/$^E, is only valid after a failed system call.
After a successful one its value is undefined.

                                        Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski                          even samurai
[EMAIL PROTECTED]                         have teddy bears and even
                                      teddy bears get drunk

Reply via email to