[fpc-pascal] Pascal pointer life cycle
spir ☣
denis.spir at gmail.com
Wed May 5 12:28:30 CEST 2010
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
More information about the fpc-pascal
mailing list