Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 17, 2012 Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
I tryed to learn how arrays works and found another strange thing: import std.stdio; int[] create() { int[5] a1 = [ 10, 20, 30, 40, 50 ]; int[] b1 = a1; writeln("b1: ", b1); return b1; } void main() { int[] a2 = create(); writeln("a2: ", a2); } Result of execution: b1: [10, 20, 30, 40, 50] a2: [-142625792, 32767, 4358059, 0, 5] Please explain what's wrong with this code? Why variable a2 contains crap? Is this another dmd/druntime bug or I missed something? |
October 17, 2012 Re: Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
Posted in reply to m0rph | On 2012-10-17, 21:17, m0rph wrote: > I tryed to learn how arrays works and found another strange thing: > > import std.stdio; > > int[] create() > { > int[5] a1 = [ 10, 20, 30, 40, 50 ]; > int[] b1 = a1; > writeln("b1: ", b1); > return b1; > } > > void main() > { > int[] a2 = create(); > writeln("a2: ", a2); > } > > Result of execution: > b1: [10, 20, 30, 40, 50] > a2: [-142625792, 32767, 4358059, 0, 5] > > Please explain what's wrong with this code? Why variable a2 contains crap? Is this another dmd/druntime bug or I missed something? b1 points to the exact same data as does a1. This data is stack- allocated, and thus a2 points to an overwritten stack frame. -- Simen |
October 17, 2012 Re: Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On Wednesday, 17 October 2012 at 19:22:05 UTC, Simen Kjaeraas wrote:
> On 2012-10-17, 21:17, m0rph wrote:
>
>> I tryed to learn how arrays works and found another strange thing:
>>
>> import std.stdio;
>>
>> int[] create()
>> {
>> int[5] a1 = [ 10, 20, 30, 40, 50 ];
>> int[] b1 = a1;
>> writeln("b1: ", b1);
>> return b1;
>> }
>>
>> void main()
>> {
>> int[] a2 = create();
>> writeln("a2: ", a2);
>> }
>>
>> Result of execution:
>> b1: [10, 20, 30, 40, 50]
>> a2: [-142625792, 32767, 4358059, 0, 5]
>>
>> Please explain what's wrong with this code? Why variable a2 contains crap? Is this another dmd/druntime bug or I missed something?
>
> b1 points to the exact same data as does a1. This data is stack-
> allocated, and thus a2 points to an overwritten stack frame.
It doesn't give an error when marking the function with safe.
@safe
int[] create()
{
}
|
October 17, 2012 Re: Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
Posted in reply to sclytrack | sclytrack:
> It doesn't give an error when marking the function with safe.
>
> @safe
> int[] create()
> {
> }
I think marking it @safe is not relevant. In theory a good type system should give an error message on similar code. I don't know if D is supposed to spot similar error situations.
Bye,
bearophile
|
October 17, 2012 Re: Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | > b1 points to the exact same data as does a1. This data is stack-
> allocated, and thus a2 points to an overwritten stack frame.
Thanks for explanation, I thought contetns of a1 are copied to the heap when assignment operator executed.
|
October 17, 2012 Re: Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, October 17, 2012 21:46:50 bearophile wrote: > sclytrack: > > It doesn't give an error when marking the function with safe. > > > > @safe > > int[] create() > > { > > } > > I think marking it @safe is not relevant. In theory a good type system should give an error message on similar code. I don't know if D is supposed to spot similar error situations. @safe is irrelevant, because the code is just plain broken in the first place. It really should be an error ( http://d.puremagic.com/issues/show_bug.cgi?id=7087 ), just like it's an error to return a pointer to a local variable. But unfortunately, since all it takes to trick the compiler is passing the slice (or pointer in the case of the pointer to a local variable) to a function which then returns that slice/pointer, there's no way for the compiler to always catch it for you. The only way that @safe could really be applicable would be if it became @system to take the address of a local variable or to slice a static array. And perhaps it should be, but that and catching the most obvious cases are all that the compiler could do to catch this for you. - Jonathan M Davis |
October 17, 2012 Re: Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 17 October 2012 at 19:46:51 UTC, bearophile wrote:
> sclytrack:
>
>> It doesn't give an error when marking the function with safe.
>>
>> @safe
>> int[] create()
>> {
>> }
>
> I think marking it @safe is not relevant. In theory a good type system should give an error message on similar code. I don't know if D is supposed to spot similar error situations.
>
> Bye,
> bearophile
If that's the case then they should call it safeR D instead of safe D.
|
October 17, 2012 Re: Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | > The only way that @safe could really be applicable would be if it became @system to take the address of a local variable or to slice a static array. And perhaps it should be, but that and catching the most obvious cases are all that the compiler could do to catch this for you.
Hmmm, you could have the compiler add a runtime check and see if slices are stack allocated (EAX >= ESP I think), then quit with an error, or alternatively it would make a copy afterwards, or at least a warning.
|
October 17, 2012 Re: Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis:
>there's no way for the compiler to always catch it for you.<
I think there are type systems able to always catch this kind of bug (conservative region analysis, it means that if it can't demonstrate the memory doesn't escape, it prudently refuses the code). D doesn't have such kind of type system.
Bye,
bearophile
|
October 17, 2012 Re: Returning dynamic array from the function | ||||
---|---|---|---|---|
| ||||
On Wednesday, October 17, 2012 13:07:13 Jonathan M Davis wrote: > The only way that @safe could really be applicable would be if it became @system to take the address of a local variable or to slice a static array. And perhaps it should be, but that and catching the most obvious cases are all that the compiler could do to catch this for you. It looks like taking the address of a local variable already is @system, but taking a slice of a static array is not. That really should change: http://d.puremagic.com/issues/show_bug.cgi?id=8838 - Jonathan M Davis |
Copyright © 1999-2021 by the D Language Foundation