On Thu, 12 Nov 2009 08:56:25 -0500, Steven Schveighoffer
<schvei...@yahoo.com> 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
Well something like this should work (note that I'm making the conversion
from T[N] to T[] explicit)
auto strstr(T,U)(T src, U substring)
if(isRandomAccessRange!T &&
isRandomAccessRange!U &&
is(ElementType!U == ElementType!T)
{ /* Do strstr */ }
char[] foo() { // Returns type char[]
char buf[100]; // Of type scope char[100]
// fill buf // "hi" is type immutable(char)[]
return strstr(buf[], "hi").dup; // returns a lent char[], which is
dup-ed into a char[], which is okay to return
}
char[] foo2() { // Returns type char[]
char buf[100]; // Of type scope char[100]
// fill buf // "hi" is type immutable(char)[]
return strstr(buf[], "hi"); // Error, strstr returns a lent char[],
not char[].
}
lent char[] foo3() { // Returns type lent char[]
char buf[100]; // Of type scope char[100]
// fill buf // "hi" is type immutable(char)[]
return strstr(buf[], "hi"); // Error, scope char[] cannot be
implicitly converted to lent char[] inside a lent char[] function:
possible escape.
}
char[] foo4() { // Returns type char[]
char buf[100]; // Of type scope char[100]
return buf; // Error, return type is char[] not
char[100].
}
char[] foo5() { // Returns type char[]
char buf[100]; // Of type scope char[100]
return buf[]; // Error, return type is char[] not
scope char[].
}
Here's an (outdated and confusing) proposal I put together a while ago
(It's pre-DIP): http://prowiki.org/wiki4d/wiki.cgi?OwnershipTypesInD In
it, I used stack and scope instead of scope and lent.