Prof Abimbola Olowofoyeku wrote:
On 19 Apr 2002 at 9:10, Adam Naumowicz wrote:
I found out that, unfortunately, the newest GPC has a changed processing of constructors. As far as I know, even the virtual methods should be identified in the compilation time in the sense, that when calling a constructor for an object (for example one with destroyed layout) the methods are called inside the constructor the static way.
That's not really what it did before. What I changed was to remove a (normally) redundant VMT pointer assignment. Usually the VMT pointer is assigned when the variable is created (i.e., at program/routine start for non-pointer objects, and after memory allocation when using `New').
Until recently, GPC *also* assigned the VMT when calling a constructor which is therefore redundant (especially when calling a constructor within `New', one could see two assignments next to each other which made it clear that one was redundant).
but let's say I have something like that:
type t=object constructor Init; procedure Proc;virtual; end;
constructor t.Init; begin Proc; end;
procedure t.Proc; begin end;
ar=array[0..10000] of t; pa=^ar; var p:pa;
begin GetMem(p,n*SizeOf(t)); p^[1].Init; end.
Then the elements of the array should know their type, that is, even after GetMem there should be a way to call the virtual method.
The elements of the array know their type and you can call the virtual method - as long as you allocate memory for the object with "New".
Indeed.
First question: Why don't you simply write `New (p)' (which works)? I suppose because you don't really want 10000 elements, but rather just a place-holder for a "large" number while you actually allocate less. Of course, it might have been a good idea to actually state this in your mail and to provide a definition of n in your code fragment above, so we wouldn't have to guess ...
Secondly: Why don't you use a schema type (`ar(n:Integer)=array[0..n-1] of t; [...] New(p,n)')? This also works. But if you want to make things extra hard for you by using place-holders and manually computed memory sizes, you should not be surprised when also the initialization gets harder ...
That said, you can initialize objects manually if you really want to, by using `SetType' (e.g., `{$local X+} SetType(p^[1], TypeOf (t)); {$endlocal}').
It still works with GPC. The problem here is using "Getmem" instead of "New". This might be an unnecessary restriction in GPC (i.e., having to use "New")
I don't think it's an "unnecessary restriction". `GetMem' just does what it says -- it allocates a block of memory and nothing more. It's a low-level routine -- use it with caution. `New' is a high-level routine for memory allocation in a Pascal context.
People sometimes get confused by the fact that both of them do the actual allocation in the same way (in GPC and also in BP AFAIR). But that's not the point -- the difference is what `New' does *besides* the initialization. Using `GetMem' you can skip those initializations ... if that's what you want ...
Frank