Thread overview
return table from local resource
Jun 25, 2012
monarch_dodra
Jun 25, 2012
bearophile
Jun 25, 2012
Timon Gehr
Jun 26, 2012
monarch_dodra
Jun 26, 2012
Timon Gehr
June 25, 2012
Just started using D. I've got a very strong background in C++. I
was making this toy program:

[CODE]import std.stdio;

int[] fun()
{
    int[3] statictab;
    writeln(statictab);
    int[] dyntab = statictab;
    writeln(dyntab);
    return dyntab;
}

void main()
{
    int[] a = fun();
    writeln(a);
}[/CODE]

First, I create a method called "fun". In it, I create on the
stack a table. I create a dynamic array that references that
table. I return the dynamic array.

Of course, this is the classic "return reference to local"
problem. I can tell the problem is there because the output I get
is:

[CODE]
[0, 0, 0]
[0, 0, 0]
[1637924, 4217180, 10] //Garbage
[/CODE]

What bothers me is that it was my understanding that the D
language standard protected me from this kind of undefined
behavior. I did make use of anything unsafe, so what gives?
Compiler not catch it but should have?

Or am I just mistaken about the safe guarantees of D?

What bothers me even more is this:

[CODE]@safe

int[] fun()
{
    int[3] statictab;
    int[] dyntab = statictab;
    return dyntab;
}

void main()
{
    int[] a = fun();
}
[/CODE]

This time, in "Safe" mode...
June 25, 2012
monarch_dodra:

> What bothers me is that it was my understanding that the D
> language standard protected me from this kind of undefined
> behavior. I did make use of anything unsafe, so what gives?
> Compiler not catch it but should have?

Currently the compiler doesn't track where is located the memory of dynamic array slices. In general it's hard to perform this analysis, so I think the D compiler isn't supposed to catch all such bugs.

On the other hand a certain amount of logic to statically detect simple cases like this one should be added. Maybe you want to add this as a Bugzilla enhancement request. If you have a strong C++ background you may even be able to write a patch in GitHub that implements a basic form of such static analysis.

Regarding @safe, it can't help you here. Since day 0 I've said @safe is a named wrongly, because it just refers to a narrow definition of memory safety, that doesn't include the class of bugs discussed here.

Bye,
bearophile
June 25, 2012
On 06/25/2012 01:11 PM, bearophile wrote:
> monarch_dodra:
>
>> What bothers me is that it was my understanding that the D
>> language standard protected me from this kind of undefined
>> behavior. I did make use of anything unsafe, so what gives?
>> Compiler not catch it but should have?
>
> Currently the compiler doesn't track where is located the memory of
> dynamic array slices. In general it's hard to perform this analysis, so
> I think the D compiler isn't supposed to catch all such bugs.
>
> On the other hand a certain amount of logic to statically detect simple
> cases like this one should be added. Maybe you want to add this as a
> Bugzilla enhancement request. If you have a strong C++ background you
> may even be able to write a patch in GitHub that implements a basic form
> of such static analysis.
>
> Regarding @safe, it can't help you here. Since day 0 I've said @safe is
> a named wrongly, because it just refers to a narrow definition of memory
> safety, that doesn't include the class of bugs discussed here.
>
> Bye,
> bearophile

It does. It is not fully implemented.
June 26, 2012
On Monday, 25 June 2012 at 12:01:22 UTC, Timon Gehr wrote:
> On 06/25/2012 01:11 PM, bearophile wrote:
>
> It does. It is not fully implemented.

Ok. That's good to know then. Thanks.

Out of sheer curiosity, if I have "potentially dangerous code, eg"

int[] fun(int i)
{
      int[3] statictab;
      int[]  = statictab
      if(i) dyntab = new int[3];;
      return dyntab;
}


I expect my compiler to refuse to compile this, because this *could* produce undefined behavior. Is this correct?
June 26, 2012
On 06/26/2012 01:22 PM, monarch_dodra wrote:
> On Monday, 25 June 2012 at 12:01:22 UTC, Timon Gehr wrote:
>> On 06/25/2012 01:11 PM, bearophile wrote:
>>
>> It does. It is not fully implemented.
>
> Ok. That's good to know then. Thanks.
>
> Out of sheer curiosity, if I have "potentially dangerous code, eg"
>
> int[] fun(int i)
> {
>       int[3] statictab;
>       int[] dyntab = statictab; // [fixed]
>       if(i) dyntab = new int[3];;
>       return dyntab;
> }
>
>
> I expect my compiler to refuse to compile this, because this *could*
> produce undefined behavior. Is this correct?

Yes, the code snipped should be refused in @safe code.