[Issue 8185] Pure functions and pointers

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Jun 4 11:46:25 PDT 2012


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



--- Comment #51 from Steven Schveighoffer <schveiguy at yahoo.com> 2012-06-04 11:48:22 PDT ---
(In reply to comment #48)
> (In reply to comment #46)
> > (In reply to comment #45)
> > > If a @trusted function accepts a pointer, it must _under no circumstances_
> > > access anything except for the pointer target, because it can be called from
> > > @safe code.
> > 
> > The point of @trusted is that it is treated as @safe, but can do unsafe things.
> >  At that point, you are telling the compiler that you know better than it does
> > that the code is safe.
> > 
> > The compiler is going to assume you did not access anything else beyond the
> > target, so you have to keep that in mind when writing a @trusted function that
> > accepts a pointer parameter.
> > 
> > Off the top of my head, I can't think of any valid usage of this, but it
> > doesn't mean we should necessarily put a restriction on @trusted functions. 
> > This is a systems language, and @trusted is a tool used to circumvent @safe-ty
> > when you know it is actually @safe.
> 
> Sorry, but I think you got this wrong. Consider this example:
> 
> ---
> void gun(int* a) @trusted;
> 
> int fun() @safe {
>   auto val = new int;
>   gun(val);
>   return *val;
> }
> ---
> 
> Here, calling gun needs to be safe under _any_ circumstances.

No, it does not.  Once you use @trusted, the compiler stops checking that it's
@safe.

> Thus, the only
> memory location which gun is allowed to access is val. If it does so by
> evaluating *(a + k), where k = (catalanNumber(5) - meaningOfLife()), that's
> fine, it's @trusted, but ultimately k must always be zero. Otherwise, it might
> violate the memory safety guarantees that need to hold for fun(). This is
> definitely not »defined by the programmer, and not expressed in possible way to
> the type system or the compiler«.

Yeah, that's a hard one to spell out in docs.  I'd recommend not writing that
function :)

But there's no way to specify this to the compiler, it must assume you have
communicated it properly.

Here is an interesting example (I pointed it out before in terms of sockaddr):

struct PacketHeader
{
   int nBytes;
   int packetType;
}

struct DataPacket
{
   PacketHeader header = {packetType:5};
   ubyte[1] data; // extends through length of packet
}

How to specify to the compiler that PacketHeader * with packetType of 5 is
really a DataPacket, and it's data member has nBytes bytes in it?

Such a well-described data structure system can be perfectly @safe, as long as
you follow the rules of construction.

Now, in order to ensure any function that receives a PacketHeader * is
@trusted, you will have to control construction of the PacketHeader somehow. 
Perhaps you make PacketHeader an opaque type, and @safe functions can therefore
never muck with the header information, or maybe you mark nBytes and packetType
as private, so it can never be changed outside the module that knows how to
build PacketHeaders.  In any case, it is wrong to assume that there isn't a
valid way to make a @trusted call that is free to go beyond the target.

-- 
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