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

ag0aep6g anonymous at example.com
Sun Sep 22 08:49:14 UTC 2019


On 22.09.19 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];
> }
[...]
> 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?

As far as I understand, converting a `ref` to a pointer is still allowed 
with DIP 1000. So they should be handled the same.

Then it's possibility 2: `foo2` should error. Your code can easily be 
expanded to demonstrate memory corruption:

----
@safe:

immutable(int)* ip;

// Exhibit B
//--------------------------
int getValue2(ref immutable int i)
{
     immutable int* my_ip = &i;
     ip = my_ip;
     return i;
}

int* foo2()
{
     immutable int value = 42;
     int[] y;
     y ~= getValue2(value); // No error
     return &y[0];
}

void main()
{
     auto p = foo2();
     import std.stdio;
     writeln(*ip); /* Prints "42". */
     writeln(*ip); /* Prints garbage. An immutable value has changed. */
}
----


More information about the Digitalmars-d mailing list