www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Static Array Idiom not working anymore.

reply SrMordred <patric.dexheimer gmail.com> writes:
this idiom for creating static array used to work, but they are 
failing now.
What changed and whats the alternative?

(from 
https://p0nce.github.io/d-idioms/# nogc-Array-Literals:-Breaking-the-Limits)

T[n] s(T, size_t n)(auto ref T[n] array) pure nothrow  nogc  safe
{
     return array;
}

void main()  nogc
{
     int[] myDynamicArray = [1, 2, 3].s; // Slice that static 
array which is on stack
}

//output:
Deprecation: slice of static array temporary returned by s([1, 2, 
3]) assigned to longer lived variable myDynamicArray
Jun 12 2018
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/12/18 10:35 AM, SrMordred wrote:
 this idiom for creating static array used to work, but they are failing 
 now.
 What changed and whats the alternative?
 
 (from 
 https://p0nce.github.io/d-idioms/# nogc-Array-Literals:-Breaking-the-Limits) 
 
 
 T[n] s(T, size_t n)(auto ref T[n] array) pure nothrow  nogc  safe
 {
      return array;
 }
 
 void main()  nogc
 {
      int[] myDynamicArray = [1, 2, 3].s; // Slice that static array 
 which is on stack
 }
 
 //output:
 Deprecation: slice of static array temporary returned by s([1, 2, 3]) 
 assigned to longer lived variable myDynamicArray
auto myStaticArray = [1,2,3].s; Now use it anywhere you need dynamic arrays as myStaticArray[]. A lot of times, it will work without having to slice it. What you are being told is that your memory is not being kept around. Essentially what you had originally was a memory corruption bug (yes, even before the deprecation happened). Don't do that anymore! Note to ponce, please update your idioms, this is NOT safe, even within the same function. Just because it does work, doesn't mean it will always work. The language makes no guarantees once the lifetime is over. -Steve
Jun 12 2018
next sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Tuesday, 12 June 2018 at 14:44:12 UTC, Steven Schveighoffer 
wrote:
 Note to ponce, please update your idioms, this is NOT safe, 
 even within the same function. Just because it does work, 
 doesn't mean it will always work. The language makes no 
 guarantees once the lifetime is over.

 -Steve
I thought it was clear enough because the comment said // Slice that static array __which is on stack__ but now I see how it can be hard to see the unsafety.
Jun 12 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/12/18 10:57 AM, Guillaume Piolat wrote:
 On Tuesday, 12 June 2018 at 14:44:12 UTC, Steven Schveighoffer wrote:
 Note to ponce, please update your idioms, this is NOT safe, even 
 within the same function. Just because it does work, doesn't mean it 
 will always work. The language makes no guarantees once the lifetime 
 is over.
I thought it was clear enough because the comment said     // Slice that static array __which is on stack__ but now I see how it can be hard to see the unsafety.
No, that's not what I mean. What I mean is: int[] arr = [1,2,3].s; int[] arr2 = [4,5,6].s; Legally, the compiler is allowed to reuse the stack memory allocated for arr for arr2. The lifetime of the arr data is over. In other words, you should NEVER do this. You should ALWAYS create a static array on the stack with a variable name, and then slice that if you need to. -Steve
Jun 12 2018
parent reply Guillaume Piolat <first.last gmail.com> writes:
On Tuesday, 12 June 2018 at 15:35:42 UTC, Steven Schveighoffer 
wrote:
 No, that's not what I mean. What I mean is:

 int[] arr = [1,2,3].s;
 int[] arr2 = [4,5,6].s;

 Legally, the compiler is allowed to reuse the stack memory 
 allocated for arr for arr2. The lifetime of the arr data is 
 over.

 -Steve
https://github.com/p0nce/d-idioms/issues/150 Especially if the stdlib has a way to do this now.
Jun 14 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/14/18 7:07 AM, Guillaume Piolat wrote:
 On Tuesday, 12 June 2018 at 15:35:42 UTC, Steven Schveighoffer wrote:
 No, that's not what I mean. What I mean is:

 int[] arr = [1,2,3].s;
 int[] arr2 = [4,5,6].s;

 Legally, the compiler is allowed to reuse the stack memory allocated 
 for arr for arr2. The lifetime of the arr data is over.

 -Steve
https://github.com/p0nce/d-idioms/issues/150 Especially if the stdlib has a way to do this now.
The Phobos PR isn't merged yet, so I think it's still valid to have this idiom, but it needs to be changed such that the implicit slicing doesn't happen. To be clear, I think the static array idiom is useful for many reasons (my favorite is avoiding issues with literal and type size mismatch), it just that the showcase usage leads to an instant dangling pointer and should be altered. -Steve
Jun 14 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, June 14, 2018 08:40:10 Steven Schveighoffer via Digitalmars-d-
learn wrote:
 On 6/14/18 7:07 AM, Guillaume Piolat wrote:
 On Tuesday, 12 June 2018 at 15:35:42 UTC, Steven Schveighoffer wrote:
 No, that's not what I mean. What I mean is:

 int[] arr = [1,2,3].s;
 int[] arr2 = [4,5,6].s;

 Legally, the compiler is allowed to reuse the stack memory allocated
 for arr for arr2. The lifetime of the arr data is over.

 -Steve
https://github.com/p0nce/d-idioms/issues/150 Especially if the stdlib has a way to do this now.
The Phobos PR isn't merged yet, so I think it's still valid to have this idiom, but it needs to be changed such that the implicit slicing doesn't happen. To be clear, I think the static array idiom is useful for many reasons (my favorite is avoiding issues with literal and type size mismatch), it just that the showcase usage leads to an instant dangling pointer and should be altered.
Yeah. The problem is not the function to create a static array. The problem is that the return value is being sliced rather than storing it on the stack and then slicing the local variable. Slicing the return value was never a safe thing to do, and if the compiler is now giving an error when you try to do it, that's actually a really good thing. - Jonathan M Davis
Jun 14 2018
prev sibling parent Guillaume Piolat <first.last gmail.com> writes:
On Tuesday, 12 June 2018 at 14:44:12 UTC, Steven Schveighoffer 
wrote:
 What you are being told is that your memory is not being kept 
 around. Essentially what you had originally was a memory 
 corruption bug (yes, even before the deprecation happened). 
 Don't do that anymore!
And a reminder that this idiom exist because _you can't have static array literals under nogc_, which is just strange (I know there are reasons, this was debated to death at the time). When D makes a decision that isn't practical, the d-idioms page get one additional entry.
Jun 12 2018
prev sibling parent reply Seb <seb wilzba.ch> writes:
On Tuesday, 12 June 2018 at 14:35:33 UTC, SrMordred wrote:
 this idiom for creating static array used to work, but they are 
 failing now.
 What changed and whats the alternative?

 (from 
 https://p0nce.github.io/d-idioms/# nogc-Array-Literals:-Breaking-the-Limits)

 T[n] s(T, size_t n)(auto ref T[n] array) pure nothrow  nogc 
  safe
 {
     return array;
 }

 void main()  nogc
 {
     int[] myDynamicArray = [1, 2, 3].s; // Slice that static 
 array which is on stack
 }

 //output:
 Deprecation: slice of static array temporary returned by s([1, 
 2, 3]) assigned to longer lived variable myDynamicArray
FYI: There's a Phobos PR for such an idiom https://github.com/dlang/phobos/pull/6489
Jun 12 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/12/18 10:54 AM, Seb wrote:
 On Tuesday, 12 June 2018 at 14:35:33 UTC, SrMordred wrote:
 this idiom for creating static array used to work, but they are 
 failing now.
 What changed and whats the alternative?

 (from 
 https://p0nce.github.io/d-idioms/# nogc-Array-Literals:-Breaking-the-Limits) 


 T[n] s(T, size_t n)(auto ref T[n] array) pure nothrow  nogc  safe
 {
     return array;
 }

 void main()  nogc
 {
     int[] myDynamicArray = [1, 2, 3].s; // Slice that static array 
 which is on stack
 }

 //output:
 Deprecation: slice of static array temporary returned by s([1, 2, 3]) 
 assigned to longer lived variable myDynamicArray
FYI: There's a Phobos PR for such an idiom https://github.com/dlang/phobos/pull/6489
Note, this only will add the 's' function (named staticArray) to phobos, it still does not allow you to implicitly slice the temporary on return. In other words, even with this change, you STILL need to do: auto myStaticArray = [1,2,3].staticArray; auto myDynamicArray = myStaticArray[]; To not have memory corruption (and avoid the deprecation message). -Steve
Jun 12 2018
parent reply SrMordred <patric.dexheimer gmail.com> writes:
On Tuesday, 12 June 2018 at 15:39:10 UTC, Steven Schveighoffer 
wrote:
 Essentially what you had originally was a memory corruption bug 
 (yes, even before the deprecation happened).
Oops , that bad.
Jun 12 2018
parent SrMordred <patric.dexheimer gmail.com> writes:
On Tuesday, 12 June 2018 at 16:27:50 UTC, SrMordred wrote:
 On Tuesday, 12 June 2018 at 15:39:10 UTC, Steven Schveighoffer 
 wrote:
 Essentially what you had originally was a memory corruption 
 bug (yes, even before the deprecation happened).
Oops , that bad.
Well, not anymore ;)
Jun 12 2018