@safe leak fix?
Denis Koroskin
2korden at gmail.com
Fri Nov 13 04:46:02 PST 2009
On Fri, 13 Nov 2009 15:29:20 +0300, Steven Schveighoffer
<schveiguy at yahoo.com> wrote:
> On Fri, 13 Nov 2009 07:01:25 -0500, Denis Koroskin <2korden at gmail.com>
> wrote:
>
>> On Fri, 13 Nov 2009 14:50:58 +0300, Steven Schveighoffer
>> <schveiguy at yahoo.com> wrote:
>>
>>> On Thu, 12 Nov 2009 18:34:48 -0500, Jason House
>>> <jason.james.house at gmail.com> wrote:
>>>
>>>> Steven Schveighoffer Wrote:
>>>>
>>>>> On Thu, 12 Nov 2009 08:45:36 -0500, Jason House
>>>>> <jason.james.house at gmail.com> wrote:
>>>>>
>>>>> > Walter Bright Wrote:
>>>>> >
>>>>> >> Jason House wrote:
>>>>> >> > At a fundamental level, safety isn't about pointers or
>>>>> references to
>>>>> >> > stack variables, but rather preventing their escape beyond
>>>>> function
>>>>> >> > scope. Scope parameters could be very useful. Scope delegates
>>>>> were
>>>>> >> > introduced for a similar reason.
>>>>> >>
>>>>> >> The problem is, they aren't so easy to prove correct.
>>>>> >
>>>>> > I understand the general problem with escape analysis, but I've
>>>>> always
>>>>> > thought of scope input as meaning @noescape. That should lead to
>>>>> easy
>>>>> > proofs. If my @noescape input (or slice of an array on the stack)
>>>>> is
>>>>> > passed to a function without @noescape, it's a compile error. That
>>>>> > reduces escape analysis to local verification.
>>>>>
>>>>> The problem is cases like this:
>>>>>
>>>>> char[] foo()
>>>>> {
>>>>> char buf[100];
>>>>> // fill buf
>>>>> return strstr(buf, "hi").dup;
>>>>> }
>>>>>
>>>>> This function is completely safe, but without full escape analysis
>>>>> the
>>>>> compiler can't tell. The problem is, you don't know how the outputs
>>>>> of a
>>>>> function are connected to its inputs. strstr cannot have its
>>>>> parameters
>>>>> marked as scope because it returns them.
>>>>>
>>>>> Scope parameters draw a rather conservative line in the sand, and
>>>>> while I
>>>>> think it's a good optimization we can get right now, it's not going
>>>>> to
>>>>> help in every case. I'm perfectly fine with @safe being
>>>>> conservative and
>>>>> @trusted not, at least the power is still there if you need it.
>>>>>
>>>>> -Steve
>>>>
>>>> what's the signature of strstr? Your example really boils down to
>>>> proving strstr is safe.
>>>
>>> The problem is, strstr isn't safe by itself, it's only safe in certain
>>> contexts. You can't mark it as @trusted either because it has the
>>> potential to be unsafe. I think if safe D heap-allocates when it
>>> passes a local address into an unprovable function such as strstr,
>>> that's fine with me.
>>>
>>> So the signature of strstr has to be unmarked (no @safe or @trusted).
>>>
>>
>> Any example of how unsafe strstr may be?
>
> Sure (with the current compiler):
>
> char[] foo()
> {
> char buf[100];
> // fill buf
> return strstr(buf, "hi"); // no .dup, buf escapes
> }
>
No, no, no! It's foo which is unsafe in your example, not strstr!
> The whole meaning of safe is fuzzy, because we don't know the safe rules
> with regards to passing references to local data. But I think the goal
> is to make it so strstr can be marked as safe. In order to do that, foo
> must be required to be unmarked or @trusted, or foo allocates buf on the
> heap.
>
> The point I was trying to make to Jason is that escape analysis is more
> complicated than just marking parameters as @noescape -- you leave out
> some provably safe functions.
>
>> BTW, strstr is no different from std.algorithm.find:
>>
>> import std.algorithm;
>>
>> char[] foo()
>> {
>> char[5] buf = ['h', 'e', 'l', 'l', 'o'];
>> char[] result = find(buf[], 'e');
>>
>> return result.dup;
>> }
>>
>> I don't see why a general-purpose searching algorithm is unsafe.
>
> It isn't inherently unsafe. It's just difficult for the compiler to see
> just from a function signature where the data flows, and escape analysis
> requires full data-flow disclosure. I think with Walter's proposal of
> allocating when a @safe function passes an address to a local to another
> @safe function is perfectly acceptable to me. I'd also like to see
> cases where you can mark the input parameter as scope, potentially
> optimizing out the allocation (but then you cannot return the scope
> parameter or a reference to any part of it).
>
> -Steve
I don't like his proposal at all. It introduces one more hidden
allocation. Why not just write
char[] buf = new char[100];
and disallow taking a slice of static array? (Andrei already hinted this
will be disallowed in @safe, if I understood him right).
Speaking about safety, I don't know how we can allow pointers in safe D:
void foo()
{
int* p = new int;
p[1000] = 0; // Will it crash or not? Is this a defined behavior, or
not?
// If not, this must be disallowed in safe D
}
And, most importantly, *why* users would want to work with pointers in
safe D at all?
More information about the Digitalmars-d
mailing list