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 | +--------------------------------------------------------------------+