On Fri, 13 Nov 2009 15:29:20 +0300, Steven Schveighoffer <schvei...@yahoo.com> wrote:

On Fri, 13 Nov 2009 07:01:25 -0500, Denis Koroskin <2kor...@gmail.com> wrote:

On Fri, 13 Nov 2009 14:50:58 +0300, Steven Schveighoffer <schvei...@yahoo.com> wrote:

On Thu, 12 Nov 2009 18:34:48 -0500, Jason House <jason.james.ho...@gmail.com> wrote:

Steven Schveighoffer Wrote:

On Thu, 12 Nov 2009 08:45:36 -0500, Jason House
<jason.james.ho...@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?

Reply via email to