CBFalconer wrote:
Frank Heckenbach wrote:
CBFalconer wrote:
The question is how much overhead to put on pointer dereference. In Pascal, unlike C, we can tell such from VAR dereference through the type system. There is a non-trivial problem involved in passing that knowledge through functional parameters. This can be handled by performing the check at the point of passage, and thenceforce treating as a VAR.
... snip ...
VAR dereference is generated directly by the compiler, and known correct (what is not necessarily known is the validity of an offset, or index, value).
If the actual var parameter is a dereferenced pointer which was disposed meanwhile, even var dereferencing can fail. Of course, disposing a pointer while a reference exists is already invalid, so you could instead try to check at `Dispose' time. But AFAICS, this would require reference counting again, or something like this ...
TYPE poo = ...; VAR pooptr : ^poo;
PROCEDURE foo(VAR p : poo); VAR oldpvalue : poo; BEGIN oldpvalue := p; p.field := ....; dispose(p); (* Compile ERROR - p is not of pointer type *) dispose(pooptr); (* fouls further p use, but why do it *) ... END;
BEGIN new(pooptr); ... foo(pooptr^); ...
At the time of calling foo pooptr is being assigned to the foo local variable p, and can be verified, just as it would be if foo received a non-var parameter. From then on (i.e. within foo) there is no way for p to become invalid, except as a result of the action of foo (or routines foo calls).
And these routines could be forward declared, or called through procedural parameters, i.e. in general there's no way for a compiler to know what they do.
Yes, it is possible to beat the system, but you have to work at it.
Sorry, but what's your point? You previously claimed that var dereferencing is "known correct". Now you say it can be beaten (but you have to work at it), and "why do it" [beat it].
That's what I said. (One could say the same thing for most other checks -- why assign out-of-range values, why dereference nil pointers, why make type errors --, so why do we need any checks at all?)
Surely, there are various ways for checks that work most of the time (I'd call them heuristic checks). But a reliable check still seems very hard in general, AFAICS.
BTW, according to the standard the `dispose(pooptr)' is invalid even if foo doesn't use p afterwards.
Pascal is NOT a concurrent system. There are no threads, etc.
These problems don't depend on threads. Aliasing is sufficient for them to arise (as the examples show), and aliasing exists in Pascal.
Frank