On Friday, 6 February 2015 at 08:58:05 UTC, Walter Bright wrote:
On 2/6/2015 12:31 AM, Kagamin wrote:
On Thursday, 5 February 2015 at 23:39:39 UTC, Walter Bright
wrote:
static void trustedMemcopy(T[] dest, T[] src) @trusted
{
assert(src.length == dest.length);
memcpy(dest.ptr, src.ptr, src.length * T.sizeof);
}
Should be enforce: assert doesn't guard against malicious
usage.
Cue my endless attempts to explain the difference between input
errors and logic errors :-(
I agree with you, that this should be an assert, but then it
cannot be @trusted. A @trusted function should provide it's
guarantee for all input that can be crafted in @safe code. This
is why this
void bar()
{
ubyte[] a;
a.ptr = 0; // arbitrary value as long as NOT from an allocator
a.len = 1;
setToZero(a);
}
is not a valid counter-example and that memcpy cannot be
@trusted. It has no safe interface.
Back to topic. Since @trusted must provide a safe interface, I
don't think it makes much sense to attach @trusted to smaller
code blocks than functions. That might not be true for the
opposite: @safe blocks where the compiler turns the safety check
back on.
This prevents that a @trusted/@safe function becoming @system
breaks the @trusted guarantee of called functions.
void bar(void* argument) @trusted { ... }
void forward() @trusted
{
// REVIEW: forwards arguments to bar, which is @trusted, so
we can
// trust forward as well
void* p = malloc(...);
bar(arguments);
free(p);
}
Changing bar to @system is a breaking change and currently a
silent one. This is a maintenance problem I see as well. Solution:
void forward() @trusted
{
void* p = malloc(...);
// safe is bar is safe, so turn compiler checks on again.
@safe { bar(p); }
free(p);
}
Introducing an error in an @trusted function is _not_ an
maintenance horror. While your @safe-ty guarantee is out of the
window, it can be catched my reviewing one function: the one
where the error is introduced in. Making a @trusted function
@system forces us to review all @trusted functions calling the
now @system function.