[Issue 8185] Pure functions and pointers

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Jun 4 06:16:06 PDT 2012


http://d.puremagic.com/issues/show_bug.cgi?id=8185



--- Comment #31 from klickverbot <code at klickverbot.at> 2012-06-04 06:18:02 PDT ---
(In reply to comment #30)
> pure doesn't restrict pointers in any way shape or form. That's an
> @safe/@trusted/@system issue, and is completely orthogonal to pure.

I guess I _might_ have understood what purity entails and what it doesn't… To
quote myself, the question here is the extent to which memory reachable by
manipulating passed in pointers is still considered local, i.e. accessible by
pure functions. This, conceptually, has nothing to do with
@safe/@trusted/@system, even though @safe code cannot manipulate pointers for
other reasons.

There are two options: Either, allow pure functions taking pointers to read
other memory locations in the same block of allocated values, or restrict
access to just the data directly pointed at (which incidentally is also what
@safe does, but, again, that's not relevant). Both options are equally valid,
and I think the current »spec« is not clear on which one should apply.

The first option, which is currently implemented in DMD, allows functions like
strlen() to be pure. On the other hand, it also makes the
semantics/implications of `pure` a lot more complex, because it links it to
something which is fundamentally not expressible by the type system, namely
that for any level of indirection, surrounding parts of the memory might be
accessible or not, depending on how it was originally allocated. This is
assuming C semantics, because, as Timon mentioned as well, OTOH the D docs
don't have a formal definition for this as all.

For example, consider »struct Node { int val; Node* next; } int foo(in Node*
head) pure;«. Using the first rule, it is almost impossible to figure out
statically what parts of the program state »foo(someHead)« depends on, because
if any of the Node instances in the chain was allocated as part of a contiguous
block (i.e. array), it would be legal for foo() to read them as well, even
though the function calling foo() might not even have been involved in the
construction of the list. Thus, the compiler is forced to always assume the
worst case in terms of optimization (at least without elaborate DFA), which, in
most D programs, is needlessly conservative.

The second option avoid such complications, and allows functions calls with
parameters on the heap (and thus pointers) to receive the same kind of
optimizations as if the parameters were passed on the stack, which might be
impractical. It is also the expected behavior if you are thinking of a pointer
literally just as an indirection to a single value stored somewhere else.

Personally, I am not sure what is the better choice; the second option seems
like the cleaner design, but I can see the merits of the first one as well. But
that's not my point – I am just trying to convince you that the »spec« (or
whatever it should really be called) needs improvement in this area, because it
frequently confuses people. Your revised version (#128) doesn't define »through
their arguments« either, yet this is the crucial point.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list