Understanding DIP 1000 semantics -- Where's the bug?

Jacob Carlborg doob at me.com
Sun Sep 22 11:03:29 UTC 2019


On 2019-09-22 04:29, Mike Franklin wrote:
> @safe:
> 
> // Exhibit A
> //--------------------------
> int getValue1(int* i)
> {
>      return *i;
> }
> 
> int* foo1()
> {
>      int value;
>      int[] y;
>      y ~= getValue1(&value); //Error: reference to local variable 
> `value` assigned to non-scope parameter `i` calling `onlineapp.getValue1`
>      return &y[0];
> }
> 
> // Exhibit B
> //--------------------------
> int getValue2(ref int i)
> {
>      return i;
> }
> 
> int* foo2()
> {
>      int value;
>      int[] y;
>      y ~= getValue2(value); // No error
>      return &y[0];
> }
> 
> // Exhibit C (Same as Exhibit A, but with `scope` attribute on `i`)
> //--------------------------
> int getValue3(scope int* i)
> {
>      return *i;
> }
> 
> int* foo3()
> {
>      int value;
>      int[] y;
>      y ~= getValue3(&value); // No error
>      return &y[0];
> }
> 
> Compile with `-preview=dip1000`.  See it live at 
> https://run.dlang.io/is/0zODCr
> 
> So, there's an inconsistency.
> 
> Possibility 1:
> Exhibit A should not emit an error
> 
> Possibility 2:
> Exhibit B should require the `scope` attribute on `i` or emit an error 
> if `foo2`.
> 
> Which is it?  Where's the bug?  Shouldn't the compiler treat `int* i` 
> and `ref i` consistently?

I think this is working as intended.

In Exhibit A, `i` is a pointer and may escape the function `getValue1`. 
Therefore it's not allowed to pass the address of a local variable to it.

In Exhibit B, `i` is a reference and cannot escape the function `getValue2`.

In Exhibit C, the `scope` annotation of `i` makes sure that `i` cannot 
escape the function `getValue3`. Therefore it's ok to pass the address 
of a local variable to it.

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list