Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!csd4.milw.wisc.edu!bionet!agate!saturn!ucscc.ucsc.edu!gorn!filbo From: filbo@gorn.santa-cruz.ca.us (Bela Lubkin) Newsgroups: comp.lang.pascal Subject: Re: Strange... The Turbo Pascal NEW command Summary: it's a "magic procedure" Message-ID: <3.filbo@gorn.santa-cruz.ca.us> Date: 2 Aug 89 15:01:23 GMT References: <845@dutrun.UUCP> Organization: R Pentomino Lines: 77 In article <845@dutrun.UUCP> mcvax!hp4nl!dutrun!winfave@uunet.uu.net (A.Verbraeck) writes: >The problem is that we do not understand the way the New >procedure works. When you call New(P) where P points to a certain >type, the New procedure allocates the correct number of bytes on >the heap. We think that the compiler inserts some extra parameters >when calling New, for the following program works _NOT_ ok: You are right. Many Turbo Pascal "standard procedures" are not procedures per se. The most obvious example is Write/WriteLn: would it be possible to write those procedures (with variable numbers of arguments, special syntax for field widths, etc.) in the language as it's documented? (This must be true in most Pascal compilers.) New and Dispose are among the library routines that are called through some trickery. When you write New(Foo), the compiler generates code similar to that which would be generated for GetMem(Foo,SizeOf(Foo^)). This is not handled by a preprocessor, nor is GetMem ever actually called explicitly, so you cannot simply write a procedure named GetMem. I don't know of any way to completely transparently replace New & Dispose. You could buy the source to the library and replace the System unit, but as a programmer using your heap code I would not find it "transparent" to have to move your unit into my library. ADDing a unit would be fine; replacing one of the vendor's, no. Hmmm. Ok, I have a kludge for you. You'll have to do some digging in the reference manual for this; my manuals are still waiting to be moved from my previous residence. Turbo's standard New/GetMem will call an exception routine if there's not enough heap to satisfy your request. You can install your routines as that exception routine, then grab ALL of Turbo's heap for yours, so all allocation attempts will generate an exception. The pointer you return must point to a memory block that actually starts a few bytes lower than the pointer points to. Store the size of the block in this extra area. This allows you to write your own Dispose procedure which doesn't require magic parameters. (I don't think there's an exception routine for Dispose -- how could it fail?) All in all, a better solution would be to write transparent replacements for GetMem/FreeMem and disallow New/Dispose. (This is easily accomplished; just declare New/Dispose procedures with no parameters. These will hide the System unit versions and prevent any attempts to call them). >program TestNew(input,output); >const > AS = 500; >type > TT = array[1..AS] of integer; > PT = ^TT; >var > IP,JP : PT; > i,j : integer; >procedure New(var P); >begin > System.New(pointer(P)); ^^^^^^^^^^ Type "pointer" acts like a "C" "void *" -- it points to a structure of size 0. New(pointer(P)) is equivalent to GetMem(P,SizeOf(P^)), or GetMem(P,0), and allocates no memory. >end; > >begin > writeln(MemAvail); > New(IP); > writeln(MemAvail); > System.New(JP); > writeln(MemAvail); > for i:=1 to AS do IP^[i]:=i; > for i:=1 to AS do JP^[i]:=0; > for j:=1 to 10 do write(IP^[j]:5); > writeln; > write('Press Enter'); > readln; >end. Bela Lubkin * * filbo@gorn.santa-cruz.ca.us CIS: 73047,1112 @ * * ...ucbvax!ucscc!gorn!filbo ^^^ REALLY slow [months] R Pentomino * Filbo @ Pyrzqxgl (408) 476-4633 & XBBS (408) 476-4945