www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to pass static array to function not by value?

reply drug <drug2004 bk.ru> writes:
I tried to pass pointer to static array but it didn't work.
Nov 22 2014
next sibling parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sat, 22 Nov 2014 18:20:44 +0400
drug via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 I tried to pass pointer to static array but it didn't work.
i tried it right now and it works. if you really want to get some help, you'd better give us something to start with. i.e. your code, minified. D is great, but it still can't grant telepathic abilities to us.
Nov 22 2014
parent reply drug <drug2004 bk.ru> writes:
On 22.11.2014 19:34, ketmar via Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 18:20:44 +0400
 drug via Digitalmars-d-learn<digitalmars-d-learn puremagic.com>  wrote:

 I tried to pass pointer to static array but it didn't work.
i tried it right now and it works. if you really want to get some help, you'd better give us something to start with. i.e. your code, minified. D is great, but it still can't grant telepathic abilities to us.
Sorry for inconvenience. http://dpaste.dzfl.pl/64ab69ae80d2 this causes stackoverflow because static array is big enough. I'd like to pass it not by value to avoid stack overflowing. Even if I use ref dmd pass it by value.
Nov 22 2014
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 11/22/2014 07:07 AM, drug wrote:

 On 22.11.2014 19:34, ketmar via Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 18:20:44 +0400
 drug via Digitalmars-d-learn<digitalmars-d-learn puremagic.com>  wrote:

 I tried to pass pointer to static array but it didn't work.
i tried it right now and it works. if you really want to get some help, you'd better give us something to start with. i.e. your code, minified. D is great, but it still can't grant telepathic abilities to us.
Sorry for inconvenience. http://dpaste.dzfl.pl/64ab69ae80d2 this causes stackoverflow because static array is big enough.
If it overflows the stack just because there are two copies on it, then it will overflow for one of them in the future. (Say, after adding another variable to main.) For example, the following program has the same problem on my system without passing any argument: import std.stdio; enum A = 65536; enum B = 50; alias MyType = int[A][B]; void main() { MyType arr; } make: *** [deneme] Segmentation fault
 I'd like to pass it not by value to avoid stack overflowing. Even if 
I use
 ref dmd pass it by value.
I would dynamically allocate the storage. There is the following convenient syntax: import std.stdio; enum A = 65536; enum B = 1000; // <-- Much larger now alias MyType = int[][]; void foo(ref MyType arr) { writeln(arr[3][40]); } void main() { auto arr = new int[][](B, A); // <-- "A elements of int[B] each" foo(arr); } Ali
Nov 22 2014
parent drug <drug2004 bk.ru> writes:
On 22.11.2014 20:26, Ali Çehreli wrote:
 On 11/22/2014 07:07 AM, drug wrote:

  > On 22.11.2014 19:34, ketmar via Digitalmars-d-learn wrote:
  >> On Sat, 22 Nov 2014 18:20:44 +0400
  >> drug via Digitalmars-d-learn<digitalmars-d-learn puremagic.com> wrote:
  >>
  >>> I tried to pass pointer to static array but it didn't work.
  >> i tried it right now and it works.
  >>
  >> if you really want to get some help, you'd better give us something to
  >> start with. i.e. your code, minified. D is great, but it still can't
  >> grant telepathic abilities to us.
  >
  > Sorry for inconvenience.
  > http://dpaste.dzfl.pl/64ab69ae80d2
  > this causes stackoverflow because static array is big enough.

 If it overflows the stack just because there are two copies on it, then
 it will overflow for one of them in the future. (Say, after adding
 another variable to main.)

 For example, the following program has the same problem on my system
 without passing any argument:

 import std.stdio;

 enum A = 65536;
 enum B = 50;

 alias MyType = int[A][B];

 void main()
 {
 MyType arr;
 }

 make: *** [deneme] Segmentation fault

  > I'd like to pass it not by value to avoid stack overflowing. Even if
 I use
  > ref dmd pass it by value.

 I would dynamically allocate the storage. There is the following
 convenient syntax:

 import std.stdio;

 enum A = 65536;
 enum B = 1000; // <-- Much larger now

 alias MyType = int[][];

 void foo(ref MyType arr)
 {
 writeln(arr[3][40]);
 }

 void main()
 {
 auto arr = new int[][](B, A); // <-- "A elements of int[B] each"
 foo(arr);
 }

 Ali
I did like you suggested, thank you.
Nov 22 2014
prev sibling next sibling parent reply "Eric" <eric makechip.com> writes:
On Saturday, 22 November 2014 at 16:07:25 UTC, drug wrote:
 On 22.11.2014 19:34, ketmar via Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 18:20:44 +0400
 drug via 
 Digitalmars-d-learn<digitalmars-d-learn puremagic.com>  wrote:

 I tried to pass pointer to static array but it didn't work.
i tried it right now and it works. if you really want to get some help, you'd better give us something to start with. i.e. your code, minified. D is great, but it still can't grant telepathic abilities to us.
Sorry for inconvenience. http://dpaste.dzfl.pl/64ab69ae80d2 this causes stackoverflow because static array is big enough. I'd like to pass it not by value to avoid stack overflowing. Even if I use ref dmd pass it by value.
Your problem is not the reference issue. D has a limit on how big static arrays can be in a function. You can make them bigger by declaring them globally, but I think even that has a limit. Try this: import std.stdio; enum A = 65536; enum B = 32; alias MyType = int[A][B]; void foo(ref MyType arr) { writeln(arr[3][3]); } MyType arr; void main() { writeln("arr[3][3] = ", arr[3][3]); foo(arr); } -Eric
Nov 22 2014
parent drug <drug2004 bk.ru> writes:
On 22.11.2014 20:26, Eric wrote:
 On Saturday, 22 November 2014 at 16:07:25 UTC, drug wrote:
 On 22.11.2014 19:34, ketmar via Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 18:20:44 +0400
 drug via Digitalmars-d-learn<digitalmars-d-learn puremagic.com> wrote:

 I tried to pass pointer to static array but it didn't work.
i tried it right now and it works. if you really want to get some help, you'd better give us something to start with. i.e. your code, minified. D is great, but it still can't grant telepathic abilities to us.
Sorry for inconvenience. http://dpaste.dzfl.pl/64ab69ae80d2 this causes stackoverflow because static array is big enough. I'd like to pass it not by value to avoid stack overflowing. Even if I use ref dmd pass it by value.
Your problem is not the reference issue. D has a limit on how big static arrays can be in a function. You can make them bigger by declaring them globally, but I think even that has a limit. Try this: import std.stdio; enum A = 65536; enum B = 32; alias MyType = int[A][B]; void foo(ref MyType arr) { writeln(arr[3][3]); } MyType arr; void main() { writeln("arr[3][3] = ", arr[3][3]); foo(arr); } -Eric
Yes, it has limit in 16 mb (from here - http://dlang.org/arrays.html#resize): "The total size of a static array cannot exceed 16Mb. A dynamic array should be used instead for such large arrays." Thank you for answers.
Nov 22 2014
prev sibling parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sat, 22 Nov 2014 19:07:14 +0400
drug via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 Sorry for inconvenience.
 http://dpaste.dzfl.pl/64ab69ae80d2
 this causes stackoverflow because static array is big enough. I'd like=20
 to pass it not by value to avoid stack overflowing. Even if I use ref=20
 dmd pass it by value.
ah, that's why we need to look at the code! ;-) what you have here is multidimensional static array, so 'ref' is not working as you expected. let's just say that you can't do this with 'ref' and static arrays, 'cause compiler will copy some of the data anyway. multidimensional static array is just a continuous region of memory, not a pointer to regions, as dynamic arrays. so compiler can't make reference to `[A][B]` (for now, at least). either use dynamic arrays as Ali suggested, or do all the pointer math manually (i.e. pass &arr[0]0] and all dimensions). it's a bad practice to have such big arrays on the stack anyway.
Nov 22 2014
parent drug <drug2004 bk.ru> writes:
On 22.11.2014 20:47, ketmar via Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 19:07:14 +0400
 drug via Digitalmars-d-learn<digitalmars-d-learn puremagic.com>  wrote:

 Sorry for inconvenience.
 http://dpaste.dzfl.pl/64ab69ae80d2
 this causes stackoverflow because static array is big enough. I'd like
 to pass it not by value to avoid stack overflowing. Even if I use ref
 dmd pass it by value.
ah, that's why we need to look at the code! ;-) what you have here is multidimensional static array, so 'ref' is not working as you expected. let's just say that you can't do this with 'ref' and static arrays, 'cause compiler will copy some of the data anyway. multidimensional static array is just a continuous region of memory, not a pointer to regions, as dynamic arrays. so compiler can't make reference to `[A][B]` (for now, at least). either use dynamic arrays as Ali suggested, or do all the pointer math manually (i.e. pass&arr[0]0] and all dimensions). it's a bad practice to have such big arrays on the stack anyway.
I didn't understand why ref didn't work. Now it's clear. Thank you.
Nov 22 2014
prev sibling next sibling parent "Eric" <eric makechip.com> writes:
On Saturday, 22 November 2014 at 15:20:55 UTC, drug wrote:
 I tried to pass pointer to static array but it didn't work.
try this: import std.stdio; void change(ref int[3] arr) { arr[1] = 6; } void main() { int[3] a = [1, 2, 3]; writeln("a = ", a); change(a); writeln("a = ", a); } -Eric
Nov 22 2014
prev sibling parent reply "Eric" <eric makechip.com> writes:
On Saturday, 22 November 2014 at 15:20:55 UTC, drug wrote:
 I tried to pass pointer to static array but it didn't work.
Also, if you really want to be lame and actually use a pointer try this: import std.stdio; void change(int *arr) { arr[1] = 6; } void main() { int[3] a = [1, 2, 3]; writeln("a = ", a); change(a.ptr); writeln("a = ", a); } Maybe this is not so lame because change() can take any length of static array. -Eric
Nov 22 2014
next sibling parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sat, 22 Nov 2014 15:45:51 +0000
Eric via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 Maybe this is not so lame because change() can take
 any length of static array.
void change (int[] arr) { arr[1] =3D 42; } void main () { int[$] a =3D [1, 2, 3]; change(a); import std.stdio : writeln; writeln(a); // [1, 42, 3] }
Nov 22 2014
parent "Eric" <eric makechip.com> writes:
On Saturday, 22 November 2014 at 15:57:40 UTC, ketmar via 
Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 15:45:51 +0000
 Eric via Digitalmars-d-learn 
 <digitalmars-d-learn puremagic.com> wrote:

 Maybe this is not so lame because change() can take
 any length of static array.
void change (int[] arr) { arr[1] = 42; } void main () { int[$] a = [1, 2, 3]; change(a); import std.stdio : writeln; writeln(a); // [1, 42, 3] }
Okay, the pointer way really is lame then:) -Eric
Nov 22 2014
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Sat, Nov 22, 2014 at 05:57:30PM +0200, ketmar via Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 15:45:51 +0000
 Eric via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:
 
 Maybe this is not so lame because change() can take
 any length of static array.
void change (int[] arr) { arr[1] = 42; } void main () { int[$] a = [1, 2, 3]; change(a);
This is actually really scary that static arrays implicitly decay to a dynamic array slice. It can cause all sorts of problems with escaping dangling references to local variables: Example #1: int[] bad(int[] arr) { return arr; } int[] equallyBad() { int[3] x = [1,2,3]; return bad(x); // oops } Example #2: struct S { int[] data; this(int[] arr) { data = arr; } } S makeS() { int[3] x = [1,2,3]; return S(x); // oops } Example #3: struct S { int[] data; this(int[] arr...) { // red flag data = arr; } } void main() { auto s = S([1,2,3]); // OK auto t = S(1,2,3); // NG } IMO, at the very least, an explicit slice should be required to turn a static array into a dynamic array slice. That way, the programmer at least has to think for 1 second (hopefully more) whether or not he should be passing a slice to a static array. T -- Those who don't understand Unix are condemned to reinvent it, poorly.
Nov 22 2014
prev sibling parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sat, 22 Nov 2014 08:07:31 -0800
"H. S. Teoh via Digitalmars-d-learn"
<digitalmars-d-learn puremagic.com> wrote:

 On Sat, Nov 22, 2014 at 05:57:30PM +0200, ketmar via Digitalmars-d-learn =
wrote:
 On Sat, 22 Nov 2014 15:45:51 +0000
 Eric via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:
=20
 Maybe this is not so lame because change() can take
 any length of static array.
=20 void change (int[] arr) { arr[1] =3D 42; } =20 void main () { int[$] a =3D [1, 2, 3]; change(a);
=20 This is actually really scary that static arrays implicitly decay to a dynamic array slice. It can cause all sorts of problems with escaping dangling references to local variables:
i don't even want to argue with that. ;-) just 'cause i'm sure that you are right, and this code shouldn't compile at all without explicit slicing of `a`. but this is what we have now, and i bet it will stay with us, 'cause "changing that will break alot of correct D code". so if we can't annihilate it, let's use it! ;-)
Nov 22 2014
parent reply drug <drug2004 bk.ru> writes:
On 22.11.2014 20:30, ketmar via Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 08:07:31 -0800
 "H. S. Teoh via Digitalmars-d-learn"
 <digitalmars-d-learn puremagic.com>  wrote:

 On Sat, Nov 22, 2014 at 05:57:30PM +0200, ketmar via Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 15:45:51 +0000
 Eric via Digitalmars-d-learn<digitalmars-d-learn puremagic.com>  wrote:

 Maybe this is not so lame because change() can take
 any length of static array.
void change (int[] arr) { arr[1] = 42; } void main () { int[$] a = [1, 2, 3]; change(a);
This is actually really scary that static arrays implicitly decay to a dynamic array slice. It can cause all sorts of problems with escaping dangling references to local variables:
i don't even want to argue with that. ;-) just 'cause i'm sure that you are right, and this code shouldn't compile at all without explicit slicing of `a`. but this is what we have now, and i bet it will stay with us, 'cause "changing that will break alot of correct D code". so if we can't annihilate it, let's use it! ;-)
Does it worth to make some compiler option that for example prohibits passing static array instead of dynamic one without slicing? Who has a lot of breakable correct D code doesn't use it, but others do if they want?
Nov 22 2014
parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sat, 22 Nov 2014 20:05:13 +0400
drug via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 Does it worth to make some compiler option that for example prohibits=20
 passing static array instead of dynamic one without slicing? Who has a=20
 lot of breakable correct D code doesn't use it, but others do if they wan=
t? Walter is hard to convince on new options. and i believe that he is right here, 'cause options that changing language semantics are a big PITAs. compiler can generate deprecation warning though, which doesn't break anything. but first we have to convince Walter that given feature must be deprecated, which is hard too. not 'cause Walter is that stubborn, but 'cause he wants to see some real-world code that will clearly benefits from deprecation first. 'cause language that deprecates some random features with each release is hardly can be considered as "mature". ;-)
Nov 22 2014
parent drug <drug2004 bk.ru> writes:
On 22.11.2014 21:22, ketmar via Digitalmars-d-learn wrote:
 On Sat, 22 Nov 2014 20:05:13 +0400
 drug via Digitalmars-d-learn<digitalmars-d-learn puremagic.com>  wrote:

 Does it worth to make some compiler option that for example prohibits
 passing static array instead of dynamic one without slicing? Who has a
 lot of breakable correct D code doesn't use it, but others do if they want?
Walter is hard to convince on new options. and i believe that he is right here, 'cause options that changing language semantics are a big PITAs. compiler can generate deprecation warning though, which doesn't break anything. but first we have to convince Walter that given feature must be deprecated, which is hard too. not 'cause Walter is that stubborn, but 'cause he wants to see some real-world code that will clearly benefits from deprecation first. 'cause language that deprecates some random features with each release is hardly can be considered as "mature". ;-)
Ok, I see. So it would be better to use not compiler for such things but a static analyzer, I guess.
Nov 22 2014