Hello,

First, I found a very good introduction material to pointers at 
http://cslibrary.stanford.edu/. The author, "Nick Parlante" (nickname?) really 
has a great pedagogical talent.

Below some code and output tracing a typical pointer's life cycle:

======= code =======
procedure PointerLifeCycle0();
var
    p : PInteger;               // ^Integer
begin
    writeln('startup:');
//    writeln('v:',p^);            // Access Violation
    writeln('p:',longword(p));    // warning not initialized

    writeln('allocation:');
    new(p);
    writeln('p:',longword(p));    // address
    writeln('v:',p^);            // random ; no error

    writeln('valuation:');
    p^ := 1;
    writeln('v:',p^);            // 1
    
    writeln('disposal:');
    dispose(p);
    writeln('p:',longword(p));    // meaningless ; no error
    writeln('v:',p^);            // trash ; no error

    writeln('nil-ization:');
    p := nil;
    writeln('p:',longword(p));    // 0
//    writeln('v:',p^);            // Access Violation
end;
====== output ======
startup:
p:3215995332
allocation:
p:9105488
v:9105500
valuation:
v:1
disposal:
p:9105488
v:9105500
nil-ization:
p:0
====================

So, I have 3 questions:
-1- Why isn't an unallocated pointer nil?
-2- Why is it at all possible to allocate a pointer without setting the 
target's value? In other word why doesn't new() take a second argument, value. 
Or, why not have this argument optional and recommend its use?
-3- Why is it at all possible to deallocate a pointer without "nil-izing" it? 
Why not have dispose() set it to nil?

Consequently, I wrote 2 procs setPointer and resetPointer:

======= code =======
procedure setPointer(var p:PInteger ; v:Integer);
begin
    new(p);
    p^ := v;
end;
procedure resetPointer(var p:PInteger ; v:Integer);
begin
    dispose(p);
    p := nil;
end;
procedure PointerLifeCycle1();
var
    p : PInteger = nil;            // manual...
begin
    writeln;
    writeln('startup:');
    write('p:',longword(p));    // warning not initialized
    writeln(' (may be automatic)');

    writeln('allocation & valuation:');
    setPointer(p, 1);
    writeln('p:',longword(p));    // address
    writeln('v:',p^);            // random ; no error

    writeln('disposal & nil-ization:');
    resetPointer(p, 1);
    writeln('p:',longword(p));    // meaningless ; no error
//    writeln('v:',p^);            // Access Violation
end;
====== output ======
startup:
p:0 (may be automatic)
allocation & valuation:
p:9105488
v:1
disposal & nil-ization:
p:0
====================

(Unfortunately, I cannot have p=nil automatic at startup.)
Is such a behaviour consistent and desirable? If yes, why does Pascal let 
dangerous pointers live? If not, what are the use cases for possibly unsafe 
pointers? And why not have builtin procs offer this behaviour anyway, when 
possible?
I won't use the above procedures because of the call (and value copy (*)) 
overhead --since my future code will do nearly everything via pointers. But I 
would love to have this semantics builtin (and then run at machine code speed, 
with no call and no copy).

Denis

(*) If the value is passed by ref, then the caller must have it stored in a 
variable.
________________________________

vit esse estrany ☣

spir.wikidot.com
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to