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

Reply via email to