The way I'm implementing user-defined pointer checking now is as follows:
program ValidatePointerDemo;
uses GPC;
{ Example pointer validation routine. Since it is used instead of nil checks, the first thing it should do is often to check for nil pointers.
Next, it checks whether the pointer lies within the allocated bounds. GPC's heap manager provides these bounds and checks them on `Dispose'. It doesn't check them on every pointer dereference as there might be other pointers around. If this doesn't happen in your program, you can use a check such as this.
Additionally, you can do any other checks you like here. If you find the pointer invalid, this procedure should not return. (After returning, the program continues by dereferencing the pointer.) } procedure MyValidatePointer (p: Pointer); begin if p = nil then NilPointerError else if (PtrCard (p) < PtrCard (HeapLow)) or (PtrCard (p) > PtrCard (HeapHigh)) then InvalidPointerError (p) end;
{ Create a invalid pointer to demonstrate the effect. } procedure Test; var c: ^Integer; begin c := Pointer (42); WriteLn (c^) end;
begin { Install the validator routine. } ValidatePointerPtr := @MyValidatePointer;
{ Run the test. } Test end.
In a real context, this would usually be done in a unit or module whose initializer could install the validator routine.
Compile with `--pointer-checking --pointer-checking-user-defined' (globally for all modules). Program code can locally turn off `pointer-checking' for critical code, without having to remeber whether `pointer-checking-user-defined' is on (which works as shown above) or off (which does a simple nil check).
Frank