Understanding DIP 1000 semantics -- Where's the bug?
ag0aep6g
anonymous at example.com
Tue Sep 24 13:35:04 UTC 2019
On 24.09.19 10:05, Sebastiaan Koppe wrote:
> On Monday, 23 September 2019 at 20:50:30 UTC, ag0aep6g wrote:
[...]
>> Not really. When you do that, DMD rejects the `return` statement, not
>> the assignment `p = foo(x);`.
>
> But that is what you want right? You want it to error out.
Not at that point. Unless `ref` implies restrictions that pointers don't
have, `foo` should compile.
> My reasoning is as follows, because dataflow analyses is missing, you
> need to simplify the body of foo to `return &x`. Then the compilers
> errors out saying you are escaping a reference and maybe you need to add
> the return annotation. After you fix that the compiler errors out saying
> "Error: address of variable x assigned to p with longer lifetime". Which
> is exactly what we want.
>
> Ergo, missing dataflow analyses.
Aside: Your reasoning is circular. You start and end with "dataflow
analysis is missing".
When using a pointer instead of `ref`, the code is rejected as expected
even with the more complex body:
----
@safe:
int* foo(int* x)
{
int* a = x;
return x;
}
void main() {
int* p;
{
int x;
p = foo(&x); /* error here */
}
}
----
So it works just fine with pointers. But maybe `ref`s are intentionally
treated differently from pointers. And maybe that means that they need
more advanced dataflow analysis which isn't currently implemented. If
that's so, it's a hole in -dip1000.
So I'm saying: Just treat `ref`s like pointers and the trouble
disappears. I suspect that it's actually intended to work like that, and
we're just looking at a good old bug.
>> It works as expected when you mark the parameter with `return`. This
>> has nothing to do with missing flow analysis. It's just a bug.
>
> I agree that it will be better to get the 2 errors the first time, but
> is that a bug?
Memory corruption in @safe code is always a bug.
[...]
> 1) fp isn't `scope int*` so the function body compiles without errors;
Yup.
> 2) you cannot return a reference to a local, so the function `fr` errors
> out correctly;
A `ref` parameter is significantly different from a true local. In the
context of DIP 1000, it's more straight-forward to treat it like a pointer.
> 3) you cannot pass a reference to a local to a non-scope argument, so
> fp(&x) errors out correctly;
Yup.
> 4) it is perfectly valid to pass a value to a ref parameter;
Not when we treat `ref` like the pointer that it really is.
Pretending that `ref` is anything but a pointer wearing a fancy hat just
leads to headaches like the one we're experiencing right now.
More information about the Digitalmars-d
mailing list