@trust is an encapsulation method, not an escape
Walter Bright via Digitalmars-d
digitalmars-d at puremagic.com
Thu Feb 5 15:39:37 PST 2015
Consider the following code excerpted from std.array.join:
static U trustedCast(U, V)(V v) @trusted { return cast(U) v; }
return trustedCast!RetType(result);
This is because the compiler would complain that the following line would not be
@safe:
return cast(RetType)(result);
The rationale is "I know it's safe, so I'll create an @trusted wrapper to
eliminate the error." What comes next is "that's cumbersome. How about a better
syntax:"
trusted {
return cast(RetType)(result);
}
? It's the rationale behind "unsafe" blocks that appear in other languages. It
seems like a perfectly reasonable request.
The trouble with it is, what if the cast is converting from an integer to a
pointer? That could lead to memory corruption. The code allows a potentially
memory corrupting operation to be inserted into code that is otherwise @safe.
The only way to deal with it is to then manually review everything about
'RetType' and 'result' to prove to oneself that it is not converting random bit
patterns into pointers. In other words, one is manually reviewing @safe code for
memory corruption errors.
This is an abject failure of @safe, @trusted, and @system.
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.
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.
More information about the Digitalmars-d
mailing list