Determining @trusted-status

Steven Schveighoffer schveiguy at gmail.com
Fri May 29 13:21:30 UTC 2020


On 5/28/20 8:09 PM, Clarice wrote:
> It seems that @safe will be de jure, whether by the current state of 
> DIP1028 or otherwise. However, I'm unsure how to responsibly determine 
> whether a FFI may be @trusted: the type signature and the body. Should I 
> run, for example, a C library through valgrind to observe any memory 
> leaks/corruption? Is it enough to trust the authors of a library (e.g. 
> SDL and OpenAL) where applying @trusted is acceptable?
> There's probably no one right answer, but I'd be very thankful for some 
> clarity, regardless.


@trusted doesn't necessarily mean "bug free", what it means is that 
given the parameters to the function, does it certify that it will only 
do @safe things with those parameters. Note that it can do whatever it 
wants elsewhere, as long as it doesn't violate the constraints of @safe 
that the caller needs.

So whether you mark something @trusted or @system highly depends on the 
behavior of the function.

A classic example is in the documentation of @safe [1]: memcpy. mempcy 
does not provide a @safe interface, because @safe code is allowed to use 
pointers as long as you only access the one item it refers to. However, 
memcpy will access a provided number of bytes *beyond* the item.

Therefore, C's memcpy should be marked @system, not @trusted. But you 
can provide a @trusted interface to memcpy because you know the semantic 
guarantees for memcpy (i.e. what it is specified to do):

@trusted void safeMemcpy(T)(T[] dst, T[] src)
{
    // must be same length
    enforce(dst.length == src.length);
    // no overlap (undefined behavior otherwise)
    enforce(dst.ptr >= src.ptr + src.length || src.ptr >= dst.ptr + 
dst.length);
    import core.stdc.string : memcpy;
    memcpy(dst.ptr, src.ptr, dst.length * T.sizeof);
}

There is no way to call this function and violate memory safety.

One has to be extra cautious though, when passing in templated 
parameters. Hidden calls such as postblit and destructors can easily not 
be @safe, so in those cases, it's wise to wrap the unsafe parts in 
@trusted lambda functions (as others have mentioned).

In my example above, I know that arrays do not have these hidden calls, 
and I'm never directly using any of the elements, just pointers.

-Steve

[1]https://dlang.org/spec/function.html#safe-interfaces


More information about the Digitalmars-d-learn mailing list