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