in; scope; scope ref; DIP1000; documentation

ag0aep6g anonymous at example.com
Thu Aug 27 21:36:13 UTC 2020


On 27.08.20 20:49, James Blachly wrote:
> 1. The thread involves 'in' qualifier. Documentation 
> (https://dlang.org/spec/function.html#param-storage) indicates that `in` 
> is defined as `scope const` and should not be used as it is not 
> implemented. **Is this [fact and recommendation] still true?**

There is this:

     https://dlang.org/changelog/2.092.0.html#preview-in

Which says that `in` is planned to become `const scope` in the future 
and there is a preview switch for it: `-preview=in`.

But these are both false (with and without `-preview=in`):

     is(void function (in int* x) == void function (const int* x))
     is(void function (in int* x) == void function (scope const int* x))

So `in` is not strictly equivalent to anything else. I'd say the 
recommendation is good: Avoid `in` until that stuff is sorted out and 
`in` actually gets lowered to `scope const` (or whatever it ends up 
meaning).

[...]
> Is "scope ref" documented somewhere specifically? I found 
> https://dlang.org/spec/function.html#scope-parameters which discusses 
> the use of `scope` with ref type parameters, but the example given is 
> pointer-based. Is it correct that `scope ref T` behaves the same as 
> `scope T*` ?

I don't think there's documentation for `scope ref`. That may be because 
`scope` doesn't affect `ref`. This is a corner of DIP 1000 that keeps 
confusing me.

Consider this function:

     int* fp(scope int** p) { return *p; }

This compiles with `-preview=dip1000`. That's because the `scope` only 
applies to the outer pointer. It doesn't apply to the inner one. So 
returning the inner pointer is fine. At least, that's how I understand 
DIP 1000.

Now consider this one:

     int* fr(scope ref int* r) { return r; }

One might expect the same result for fr. A `ref` is pretty much the same 
thing as a pointer, isn't it? But you actually get an error: "scope 
variable `r` may not be returned". I think that's because the `scope` 
doesn't apply to the `ref` part of the parameter; it applies to the pointer.

Similarly, this compiles:

     int* fp(int* p) { return p; }

But this doesn't:

     int* fr(ref int r) { return &r; }

Apparently, a `ref` is not "pretty much the same thing as a pointer". 
It's more restricted. It acts like a `scope` pointer without needing the 
`scope` annotation. Unfortunately, this isn't documented, as far as I 
can tell.

> Regarding `scope` more generally, DIP1000 shows as "superseded" -- **can 
> I still rely on this document for guidance?** We have a `-dip1000` flag 
> but a superseded DIP. The discordance is extremely confusing.
> 
> 
> I am glad D is iterating quickly and improving on safety, but I have 
> found that documentation may not well recent changes in this area.

Agreed. The documentation is in a bad state. The information is spread 
over documents, forum posts, and of course the implementation in DMD. 
And all of those are wrong/outdated in parts.

Regarding the different sources of information:

1) Start with the spec 
(<https://dlang.org/spec/function.html#scope-parameters>). Unlike DIP 
documents, the spec is being updated. It might be incomplete or have 
errors, but it at least has a chance to get fixed.

2) Ignore the DIP document 
(<https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md>). 
Only refer to it as a last resort. Any other source is more likely to be 
correct.

3) Do check what the compiler does, but don't trust it blindly. The 
implementation still has some serious bugs. A personal favorite: 
<https://issues.dlang.org/show_bug.cgi?id=20150>

4) Bugzilla (<https://issues.dlang.org>): If a bug report demonstrates a 
safety violation with only @safe code, it's valid. If it doesn't, 
there's a significant chance that the reporter missed some detail about 
`scope` and the issue ends up being invalid.

> Consequently I am reluctant to use (newer) features related to memory 
> safety. If this is all comprehensively documented somewhere please let 
> me know!

For the time being, I think it's perfectly fine to ignore 
`-preview=dip1000`. The feature is clearly not finished.


More information about the Digitalmars-d-learn mailing list