misplaced @trust?
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Thu Feb 5 08:50:18 PST 2015
Reading the thread in bug report
https://issues.dlang.org/show_bug.cgi?id=14125 gets me thinking, perhaps
@trusted is mis-designed.
At the moment, a @trusted function is the same as a @system function,
but is allowed to be called from a @safe function. And that's it.
But a @trusted function may only need to be marked @trusted because of a
few lines of code. So we now use this mechanism where we mark the
@trusted portions with a lambda or static nested function, and call that
internally, and mark the entire function @safe.
The benefit of this is, for the 90% of the code that is @safe, the
compiler is used as a tool to check the @safe-ty of the function. For
the 10% that isn't, we have contained it and marked it, and we can focus
on that portion for scrutiny. This becomes EXTREMELY important when it
comes to maintenance.
For example, if a @trusted function has some code added to it, the new
code needs to be measured to see if it really is safe to call from a
@safe function. This may be no easy feat.
At least with the @trusted inner function/lambda, you limit yourself to
the code that has been marked as such, and you don't need to worry about
the actual @safe code that is added to the function.
Or do you?... the problem with this mentality is interactions with data
inside the @safe code after a @trusted function is called can still be
subject to memory safety issues. An example (using static functions for
clarity):
void foo() @safe
{
static auto tmalloc(size_t x) @trusted {return (cast(int *)malloc(x
* sizeof(int)))[0..x];}
static void tfree(void[] arr) @trusted {free(arr.ptr);}
auto mem = tmalloc(100);
tfree(mem);
mem[0] = 5;
}
Note that the final line in the function, setting mem[0] to 5, is the
only unsafe part. it's safe to malloc, it's safe to free as long as you
don't ever refer to that memory again.
But the problem with the above is that @trusted is not needed to apply
to the mem[0] = 5 call. And imagine that the mem[0] = 5 function may be
simply added, by another person who didn't understand the context.
Marking the whole function as safe is kind of meaningless here.
Changing gears, one of the issues raised in the aforementioned bug is
that a function like this really should be marked trusted in its
entirety. But what does this actually mean?
When we mark a function @safe, we can assume that the compiler has
checked it for us. When we mark a function @trusted, we can assume the
compiler has NOT checked it for us. But how does this help? A @safe
function can call a @trusted function. So there is little difference
between a @safe and a @trusted function from an API point of view. I
would contend that @trusted really should NEVER HAVE BEEN a function
attribute. You may as well call them all @safe, there is no difference.
What I think we need to approach this correctly is that instead of
marking *functions* with @trusted, we need to mark *data* and *calls*
with @trusted. Once data is used inside a @trusted island, it becomes
tainted with the @trusted mark. The compiler can no longer guarantee
safety for that data.
So how can we implement this without too much pain? I envision that we
can mark lines or blocks inside a @safe function as @trusted (a @trusted
block inside a @system function would be a no-op, but allowed). I also
envision that any variable used inside the function is internally marked
as @safe until it's used in a @trusted block, and then is marked as
@trusted (again internally, no requirement to mark in syntax). If at any
time during compilation a @trusted variable is used in @safe code, it's
a compile error.
There may be situations in which you DO need this to work, and in those
cases, I would say a cast(@safe) could get rid of that mark. For
example, if you want to return the result of a @trusted call in a @safe
function.
Such a change would be somewhat disruptive, but much more in line with
what @trusted calls really mean.
I've left some of the details fuzzy on purpose, because I'm not a
compiler writer :)
Destroy
-Steve
More information about the Digitalmars-d
mailing list