@trusted and return ref

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Feb 26 08:25:59 PST 2015


On 2/24/15 5:37 PM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= 
<ola.fosheim.grostad+dlang at gmail.com>" wrote:
> Since neither Andrei or Walter are able to say something sensible on
> these issues when asked, I apparently need to learn something about the
> "consistency" of C memory safety.
>
> I'm happy to listen to anyone who can explain this to me:
>
> 1. My understanding is that @trusted is supposed to give memory safety
> escapes by providing a context which reestablish a memory safety context
> on return.
>
> Yet in this thread
> http://forum.dlang.org/thread/mcik3j$153g$1@digitalmars.com it is stated
> that this paradigm is an example of «careful use of @trusted»:
>
>      count = (() @trusted => cast(uint*) malloc(uint.sizeof))();
>      …arbitrary code…
>      (() @trusted => free(count))();

This isn't exactly what is happening.

First, malloc should be safe, in the same way new is safe. The fact that 
@trusted is needed is somewhat incorrect in my opinion.

Where @trusted SHOULD be needed is for `free`.

Now, I disagree that using a @trusted delegate for the free is the right 
thing to do. As soon as you free count, it is no longer safe, because 
it's a dangling pointer.

I would say THIS is somewhat correct:

(() @trusted {free(count); count=null;})();

This takes something that is validly safe, and keeps the safety by 
ensuring the pointer is no longer dangling.

However, we have an issue here. At any point inside the code, you could do:

oldcount = count;

And now, there is still potentially a dangling pointer somewhere. This 
means every place count is used must be checked. In this case, all uses 
of count have to be re-checked when the file is edited.

Because count leaks the memory details of the trusted call to free (In 
other words, the fact that count, or any copy of it, can become a 
dangling pointer), I believe every call in that type that deals with 
count should be marked trusted.

This is a great example of why @trusted is mostly a convention thing, 
and not an enforceable thing. And it's very difficult to get right. 
There is no way to say "compiler, count is tainted. Please error 
whenever anyone uses count without marking that code as @trusted."

> They way I see it, this is equivalent to typing a reinterpret_casting
> malloc and free as memorysafe operations in isolation, basically
> providing a malloc!int() and free() as memory safe functions. But why is
> malloc and free not considered safe by default then? These @trusted
> functions clearly cannot prevent leaks within their own context. You
> would need a @trusted-only storage class on the receiving pointer to do
> that and a @trusted move type.
>
> If this is careful use of @trusted, then I don't see the point of having
> @trusted at all. What is the purpose? What is it meant to cover? In
> order for @trusted to make sense in this code segment (
> http://dpaste.dzfl.pl/f3d854feede9 ) I would say that the whole class
> will have to be marked @trusted. Is that possible?

I agree. I think it's possible, like this:

struct RCArray(E) {
@trusted:

But it doesn't help with mechanical checking -- @trusted is still 
basically more dangerous @system code.

-Steve


More information about the Digitalmars-d-learn mailing list