On Tuesday 15 Dec 2009 17:14:25 Philip Potter wrote:
> 2009/12/15 Shlomi Fish <shlo...@iglu.org.il>:
> > On Tuesday 15 Dec 2009 15:53:28 Philip Potter wrote:
> >> How can "Illegal division by zero" be a compile-time error? It seems
> >> clear to me that it's a run-time error, which the optimizer has
> >> (wrongly) decided to raise at compile-time.
> >
> > Well, the Perl compiler tends to collapse constants. So if it sees
> > something like:
> >
> > <<<
> > ... ( CONSTANT_EXPR() / 0 ) ...
> >
> >
> > it will try to find the value of "CONSTANT_EXPR() / 0" so it can optimise
> > it as a constant for the interpreter, and then get a fault there. It's a
> > standard optimisation technique that also exists in other compilers such
> > as gcc that are collapsing such constant expressions. So it does get
> > evaluated at compile- time and as such should be avoided.
> 
> I'm well aware of constant folding, and yes it is a standard
> technique. But your description of it is incorrect.

Why?

> 
> If evaluating a constant expression results in a runtime exception,
> that runtime exception must happen at runtime, and not at compile
> time. In general, it is the duty of an optimizer never to change
> program behaviour, only performance.
> 

But this is a case where the compiler evaluates a constant expression and it 
results in an exception. So it cannot store it as a folded constant on the 
side for the run-time place. As a result, it throws a compile-time error.

> Therefore an optimizer which tries to fold a constant expression at
> compile time only to find a divide by zero exception should write code
> which raises a divide by zero exception at runtime. Raising a divide
> by zero exception at compile time is not what the original program
> did, and so it's not what the optimizer should do either.

Why?

> 
> If an optimizer *were* allowed to move runtime errors to compile time,
> it wouldn't just prevent use of 1/0. The following reasonable (if
> unrealistic) example would not be guaranteed to compile:
> 
> # Check if a division will emit any sort of exception (divide by zero,
> overflow, underflow, NaN, whatever)
> sub check_division {
>     my ($n, $d) = @_;
>     eval { $n/$d};
>     return "Invalid division" if $@;
>     return "Valid division";
> }
> 
> # and elsewhere...
> 
> check_division(1,0);
> 
> Why? Because if a sufficiently clever optimizer saw that somewhere in
> your code you call check_division(1,0), it could decide to inline the
> function there. And once it's done that, it can propagate the
> constants 1 and 0 into the local versions of the variables $n and $d,
> producing the constant expression 1/0 within the eval block. Now it
> merrily decides to calculate this expression's value at compile time,
> only to emit a compile-time error. If this error had happened at
> runtime, the program would have caught it and functioned entirely
> correctly; but by moving the exception to compile time -- and out of
> the eval block which was supposed to catch any exceptions -- the
> program won't even compile.

Well, Perl's optimizer is not that smart. It does not inline such functions 
because it doesn't know how many places they will get called. So you're spared 
in this case.

> 
> If I am supposed to defend against such an overzealous optimizer, how
> would I write code that uses any block eval to catch exceptions? A
> sufficiently advanced optimizer could always use some method like that
> described above to precalculate the results of the eval, triggering an
> exception at compile time instead of runtime. Therefore block eval
> could never be guaranteed to catch runtime exceptions!

Well, a program can always have user-input (from files, STDIN, @ARGV, etc.) 
which no compiler or optimiser can predict. Sometimes this input will trigger 
certain exceptions which cannot be folded.

Regards,

        Shlomi Fish

-- 
-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
Original Riddles - http://www.shlomifish.org/puzzles/

Bzr is slower than Subversion in combination with Sourceforge. 
( By: http://dazjorz.com/ )

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to