[comp.lang.pascal] Turbo bug with VAR parameters

dgil@pa.reuter.COM (Dave Gillett) (01/29/91)

     Consider the following trivial example:

var
  Global : String [255];

  procedure Foo (VAR FooStr : String [255]);

  begin
    FooStr := 'abcdefghijklmnopqrstuvwxyz';
  end { Foo };

  procedure Bar (VAR BarStr : String [255]);

  begin
    Foo (BarStr);
  end { Bar };

begin
  Bar (Global);
end.

     When I compile this using version 5.5 of Turbo Pascal (okay, this might
be fixed in 6.0 for all I know), Foo gets compiled to access FooStr by
reference rather than by value; apparently, as a pointer back into the
previous stack frame.  Similarly, Bar gets compiled to generate such access
for BarStr.
     The problem is that, at run-time, Foo trashes Bar's stack frame, instead
of reaching all the way back to the global context to resolve FooStr -> Global.

     I can understand that at the point that Foo is being compiled, it cannot
tell what the calling stack will look like.  And presumably the code to look
back a single level can easily be generated inline and is pretty efficient.
So generating "correct" code for this case may be impractical.
     However:  When Bar is being compiled, the compiler *must* already know
that Foo expects a VAR argument (it does other kinds of type-checking on the
call!).  And so if the compiler cannot generate correct code for this case,
it's not unreasonable to expect *at least* a diagnostic warning that the
passing of VAR parameters as VAR parameters is not supported.

     It *is* unreasonable to expect the programmer not only to manually
program around this (via trivial use of temporaries), but also manually
diagnose and locate instances of this.
                                              Dave

CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu ( Karl Brendel) (02/01/91)

In article 683@saxony.pa.reuter.COM, <dgil@pa.reuter.com>
  (Dave Gillett) wrote:

>     Consider the following trivial example:
>
>var
>  Global : String [255];
>
>  procedure Foo (VAR FooStr : String [255]);
>
>  begin
>    FooStr := 'abcdefghijklmnopqrstuvwxyz';
>  end { Foo };
>
>  procedure Bar (VAR BarStr : String [255]);
>
>  begin
>    Foo (BarStr);
>  end { Bar };
>
>begin
>  Bar (Global);
>end.
>
>     When I compile this using version 5.5 of Turbo Pascal (okay,
>this might be fixed in 6.0 for all I know), Foo gets compiled to
>access FooStr by reference rather than by value; apparently, as a
>pointer back into the previous stack frame.  Similarly, Bar gets
>compiled to generate such access for BarStr.
>     The problem is that, at run-time, Foo trashes Bar's stack
>frame, instead of reaching all the way back to the global context to
>resolve FooStr -> Global.
>
[...remainder deleted...]

Are you sure you're seeing what you think you are? I modified your
example code sufficiently to allow it to compile (under 5.5). (TPas
didn't like your declaration of VAR parameters as "String [255]".) I
used these compiler switches for testing:

     In TPC.CFG: /$V-
                 /$O+

      In the program proper: {$L+,D+,S-,R-}

Loading the program under TD 2.01, I examined the resulting code in
a CPU window, and traced through its execution several times. It was
very apparent that both the program code and system library code
properly passed the address of Global to the code which did the
actual assignment. No stack problems of any kind were apparent.

Try this yourself _with your example_. If you can recreate the
problem _with the example_, please email me. If not, please
create a similarly small example which _does_ demonstrate the
problem and repost.

Cheers--

+--------------------------------------------------------------------+
| Karl Brendel                           Centers for Disease Control |
| Internet: CDCKAB@EMUVM1.BITNET         Epidemiology Program Office |
| Bitnet: CDCKAB@EMUVM1                  Atlanta, GA, USA            |
|                        Home of Epi Info 5.0                        |
+--------------------------------------------------------------------+