[comp.lang.ada] Optimization creating errors

karl@grebyn.COM (Karl A. Nyberg) (01/22/88)

[Ed. Forwarded message.]

Date: Thu, 21 Jan 88 15:15:34 cst
From: ctvax!sam (Sam Mize)
Subject: Optimization creating errors

Concerning Noam Tene's reply to Norman Cohen, about optimization.

1. A DETAIL :
>VAX ADA does NOT use the optimizer by default... if it had it would have
>been a bug.

Yes it does.  Check 'Developing Ada Programs on VAX/VMS,' page A-7.  I
think that /NOOPTIMIZE would be a better default, but oh well.

2. THE PARTICULAR PROGRAM :

  (The salient bits are :
>  type ACCESS_STRING is access STRING;
>  procedure DISPOSE is new UNCHECKED_DEALLOCATION (STRING, ACCESS_STRING);
>  A: ACCESS_STRING := new STRING'("Ceci est un exemple...");
>  B: constant STRING := A.all;
>begin
> DISPOSE (A);
> TEXT_IO.PUT_LINE (B);

Declaring B as a new non-accessed object, to me, explicitly requests that
new storage be allocated for B.  Referring to A.All explicitly de-references 
the pointer and asks that the value of A be copied into the storage for B.  
This is how you do that in Ada.  This code should let you safely copy the
value an access variable points at, then pitch the access variable.  If it 
doesn't, then there's just no way to do that in Ada.

In effect, the compiler has changed B's type from STRING to ACCESS_STRING,
and then assigned it the access value.  This WOULD be an error.  It is a
change to the deeper semantics of the program, not just a rearrangement for
speed or space.

By the way, there's another reason A's accessed value and B should not share
the same space: A dereferences to a variable, while B is declared a constant.

3. GENERALIZATONS

>I think that expecting the results of an optimized compilation
>to be the SAME as those of the non optimized one for erroneous
>programs (or bad programs on the edge) is ridiculous.

I agree, but the program in question is neither erroneous nor on the edge.

>The concept of an erroneous program leaves the responsibility on the
>programmer, not the compiler.

Exactly.  I am responsible for the programs I write.  The compiler can
help me in some limited ways.  Formally stating what uses of the language
are "erroneous" but not compiler-checkable will (hopefully) help keep 
programmers from using some of the compiler-dependent tricks that are
common today.  These tricks make programs faster, smaller, incomprehensible,
unportable and unmaintainable.

In any language, after all, you CAN do things you shouldn't.  A compiler is 
a limited artifact, while programmers have boundless imagination.

>The program as you said is not erroneous.  However the vague resemblance
>is fatal for any optimizer... You're asking too much from the optimizer.
>If you want such a program to work DON'T use an optimizer on it.

Mr. Tene, my degree work was not in the area of compilation and optimization
techniques.  How can I know what the optimizer is or is not likely to do?
How can I know when I am writing "such a program" without studying the 
optimization strategies of the compiler in question?

Should I therefore never use an optimizer?  Or should I just never trust any
of my code, if optimized, to do what I expect?

>You may as well compile with a NOCHECK qualifier and complain that the
>compiler does not raise the necessary exceptions...

A NOCHECK qualifier asks the compiler not to check for, or complain about,
errors in my code.  An OPTIMIZE qualifier asks the compiler to create code
that does the same thing, but rearranged for space or time.  Neither asks
the compiler to introduce errors into a correct program.

Of course, we have to understand that optimizers will have errors in them.
As they get more sophisticated, they will have more sophisticated errors.
This isn't unexpected, or disastrous, or reprehensible on DEC's part.

But it IS an error.

Sam Mize