On Thursday, 5 February 2015 at 23:39:39 UTC, Walter Bright wrote:
The solution is to regard @trusted as a means of encapsulating
unsafe operations, not escaping them. Encapsulating them means
that the interface from the @trusted code is such that it is
usable from safe code without having to manually review the
safe code for memory safety. For example (also from std.array):
static void trustedMemcopy(T[] dest, T[] src) @trusted
{
assert(src.length == dest.length);
memcpy(dest.ptr, src.ptr, src.length * T.sizeof);
}
I don't have to review callers of trustedMemory() because it
encapsulates an unsafe operation (memcpy) with a safe interface.
If I understand correctly, your rule o be a trusted function is:
"Unable to create a memory corrutpion whatever the arguments".
But here:
- dest or src could be the null slice
- the assert would go away in release
So I though this example _could_ corrupt memory?
The reason @trusted applies only to functions, and not to
blocks of code, is that functions are the construct in D that
provides an interface. Arbitrary blocks of code do not have a
structured interface. Adding @trusted { code } support will
encourage incorrect uses like the opening example. The
existence of @trusted blocks will require review of every line
of code in the function that encloses it, and transitively
every function that calls it!
Adding @trusted as a function attribute, on the other hand,
only requires review of the function's interface to determine
if it is acceptable to use in safe code. Safety review of its
callers is unnecessary.