www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Does 'D' language supports 'C' like VLA?

reply "BS & LD" <sasho648 gmail.com> writes:
As you know in 'C' you can create a variable-length-array using 
variably modified type and a run-time variable allocating a 
storage for it - the same way for any local (normally using the 
stack).

However in 'D' I don't see such feature. Code like this fails:

void main()
{
     size_t szArr = 3;

     int[szArr] arr;
}

With this error message:

error: variable szArr cannot be read at compile time
      int[szArr] arr;

Life example - http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf

Note:  I'm also amazed why 'D' compiler can't detect that 'szArr' 
is a constant anyway.
Apr 13 2015
next sibling parent reply "CraigDillabaugh" <craig.dillabaugh gmail.com> writes:
On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array using 
 variably modified type and a run-time variable allocating a 
 storage for it - the same way for any local (normally using the 
 stack).

 However in 'D' I don't see such feature. Code like this fails:

 void main()
 {
     size_t szArr = 3;

     int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
      int[szArr] arr;

 Life example - 
 http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf

 Note:  I'm also amazed why 'D' compiler can't detect that 
 'szArr' is a constant anyway.
This likely belongs in D.learn. What you are looking for is: int[] arr; arr.length = 3;
Apr 13 2015
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 13 April 2015 at 17:02:13 UTC, CraigDillabaugh wrote:
 On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array 
 using variably modified type and a run-time variable 
 allocating a storage for it - the same way for any local 
 (normally using the stack).

 However in 'D' I don't see such feature. Code like this fails:

 void main()
 {
    size_t szArr = 3;

    int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
     int[szArr] arr;

 Life example - 
 http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf

 Note:  I'm also amazed why 'D' compiler can't detect that 
 'szArr' is a constant anyway.
This likely belongs in D.learn. What you are looking for is: int[] arr; arr.length = 3;
Eww. auto arr = new int[3]; Also, I think he's referring to something slightly different.
Apr 13 2015
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 13 April 2015 at 17:04:51 UTC, John Colvin wrote:
 Eww.

 auto arr = new int[3];

 Also, I think he's referring to something slightly different.
IMO, that shouldn't be too difficult to promote that on stack if the reference do not escape in most cases.
Apr 13 2015
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 13 April 2015 at 19:45:37 UTC, deadalnix wrote:
 On Monday, 13 April 2015 at 17:04:51 UTC, John Colvin wrote:
 Eww.

 auto arr = new int[3];

 Also, I think he's referring to something slightly different.
IMO, that shouldn't be too difficult to promote that on stack if the reference do not escape in most cases.
The problem is that the size isn't necessarily known. I guess the compiler could put in a branch, but at that point you'd probably want to give the programmer control and have a way of making it explicit.
Apr 14 2015
next sibling parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Tuesday, 14 April 2015 at 07:06:24 UTC, John Colvin wrote:
 The problem is that the size isn't necessarily known.
C backends have alloca as a primitive: http://llvm.org/docs/LangRef.html#alloca-instruction
 I guess the compiler could put in a branch, but at that point 
 you'd probably want to give the programmer control and have a 
 way of making it explicit.
A compiler hint is the right thing to do.
Apr 14 2015
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
John Colvin:

 The problem is that the size isn't necessarily known.
The size is generally known only at run-time, that's the point.
 I guess the compiler could put in a branch, but at that point 
 you'd probably want to give the programmer control and have a 
 way of making it explicit.
You don't forget to put branches added by the compiler, so it's safer. Generally you prefer something that's guaranteed to be allocated on the stack when it's small and there's enough stack. An array allocation annotated with "scope", perhaps. Bye, bearophile
Apr 14 2015
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Tuesday, 14 April 2015 at 07:30:22 UTC, bearophile wrote:
 Generally you prefer something that's guaranteed to be 
 allocated on the stack when it's small and there's enough 
 stack. An array allocation annotated with "scope", perhaps.
VLAs can save stackspace compared to fixed max sized arrays, but add recursion and try to figure out the right threshold between small and large? You can't? So you need whole program analysis...
Apr 14 2015
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Tuesday, 14 April 2015 at 07:34:28 UTC, Ola Fosheim Grøstad 
wrote:
 VLAs can save stackspace compared to fixed max sized arrays, 
 but add recursion and try to figure out the right threshold 
 between small and large? You can't? So you need whole program 
 analysis...
To be clear: you get many of the same problems with fixed sized arrays (but not all) if you cannot prevent recursion. Maybe the better option is to have a pragmas for "max stack frame size in bytes" and "max size for this VLA". Then you can estimate the stack use by worst case recursive depth and let the backend choose where to allocate if the max size for the VLA can exceed the headroom left in a max-sized stack frame.
Apr 14 2015
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Tuesday, 14 April 2015 at 07:06:24 UTC, John Colvin wrote:
 On Monday, 13 April 2015 at 19:45:37 UTC, deadalnix wrote:
 On Monday, 13 April 2015 at 17:04:51 UTC, John Colvin wrote:
 Eww.

 auto arr = new int[3];

 Also, I think he's referring to something slightly different.
IMO, that shouldn't be too difficult to promote that on stack if the reference do not escape in most cases.
The problem is that the size isn't necessarily known. I guess the compiler could put in a branch, but at that point you'd probably want to give the programmer control and have a way of making it explicit.
The branch being way cheaper than an allocation anyway, and likely to be very predictable, I'd go for it anyway. You can always add a compiler flag --max-stack-promotion-size=XXX to configure the thing, with a sensible default. This approach is far preferable as the compiler can do it AFTER inlining take place, so can promote stuff on the stack that don't like you'd be able to looking at the code.
Apr 14 2015
prev sibling parent reply "BS & LD" <sasho648 gmail.com> writes:
On Monday, 13 April 2015 at 17:02:13 UTC, CraigDillabaugh wrote:
 On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array 
 using variably modified type and a run-time variable 
 allocating a storage for it - the same way for any local 
 (normally using the stack).

 However in 'D' I don't see such feature. Code like this fails:

 void main()
 {
    size_t szArr = 3;

    int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
     int[szArr] arr;

 Life example - 
 http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf

 Note:  I'm also amazed why 'D' compiler can't detect that 
 'szArr' is a constant anyway.
This likely belongs in D.learn. What you are looking for is: int[] arr; arr.length = 3;
I suppose this will allocate the array on the 'heap' or it's storage will last past the function scope doesn't it? What I want is to allocate such variable-length-array on the stack as any other local variable.
Apr 13 2015
next sibling parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Monday, 13 April 2015 at 17:05:59 UTC, BS & LD wrote:
 On Monday, 13 April 2015 at 17:02:13 UTC, CraigDillabaugh wrote:
 On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array 
 using variably modified type and a run-time variable 
 allocating a storage for it - the same way for any local 
 (normally using the stack).

 However in 'D' I don't see such feature. Code like this fails:

 void main()
 {
   size_t szArr = 3;

   int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
    int[szArr] arr;

 Life example - 
 http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf

 Note:  I'm also amazed why 'D' compiler can't detect that 
 'szArr' is a constant anyway.
This likely belongs in D.learn. What you are looking for is: int[] arr; arr.length = 3;
I suppose this will allocate the array on the 'heap' or it's storage will last past the function scope doesn't it? What I want is to allocate such variable-length-array on the stack as any other local variable.
I suppose alloca will do it (somewhat unsafe?).
Apr 13 2015
prev sibling next sibling parent reply "CraigDillabaugh" <craig.dillabaugh gmail.com> writes:
On Monday, 13 April 2015 at 17:05:59 UTC, BS & LD wrote:
 On Monday, 13 April 2015 at 17:02:13 UTC, CraigDillabaugh wrote:
 On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array 
 using variably modified type and a run-time variable 
 allocating a storage for it - the same way for any local 
 (normally using the stack).

 However in 'D' I don't see such feature. Code like this fails:

 void main()
 {
   size_t szArr = 3;

   int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
    int[szArr] arr;

 Life example - 
 http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf

 Note:  I'm also amazed why 'D' compiler can't detect that 
 'szArr' is a constant anyway.
This likely belongs in D.learn. What you are looking for is: int[] arr; arr.length = 3;
I suppose this will allocate the array on the 'heap' or it's storage will last past the function scope doesn't it? What I want is to allocate such variable-length-array on the stack as any other local variable.
Yes, and as John pointed out it isn't the nicest way to do this. Sorry for the noise.
Apr 13 2015
parent "CraigDillabaugh" <craig.dillabaugh gmail.com> writes:
On Monday, 13 April 2015 at 17:08:57 UTC, CraigDillabaugh wrote:
 On Monday, 13 April 2015 at 17:05:59 UTC, BS & LD wrote:
 On Monday, 13 April 2015 at 17:02:13 UTC, CraigDillabaugh 
 wrote:
 On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array 
 using variably modified type and a run-time variable 
 allocating a storage for it - the same way for any local 
 (normally using the stack).

 However in 'D' I don't see such feature. Code like this 
 fails:

 void main()
 {
  size_t szArr = 3;

  int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
   int[szArr] arr;

 Life example - 
 http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf

 Note:  I'm also amazed why 'D' compiler can't detect that 
 'szArr' is a constant anyway.
This likely belongs in D.learn. What you are looking for is: int[] arr; arr.length = 3;
I suppose this will allocate the array on the 'heap' or it's storage will last past the function scope doesn't it? What I want is to allocate such variable-length-array on the stack as any other local variable.
Yes, and as John pointed out it isn't the nicest way to do this. Sorry for the noise.
I should mention that while it is on the heap, the storage should get GC'd.
Apr 13 2015
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 13 April 2015 at 17:05:59 UTC, BS & LD wrote:
 On Monday, 13 April 2015 at 17:02:13 UTC, CraigDillabaugh wrote:
 On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array 
 using variably modified type and a run-time variable 
 allocating a storage for it - the same way for any local 
 (normally using the stack).

 However in 'D' I don't see such feature. Code like this fails:

 void main()
 {
   size_t szArr = 3;

   int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
    int[szArr] arr;

 Life example - 
 http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf

 Note:  I'm also amazed why 'D' compiler can't detect that 
 'szArr' is a constant anyway.
It can, but allowing any variable that happens to be determined at compile-time to be used by other compile-time constructs just doesn't scale, especially with D's extensive meta-programming abilities.
 int[] arr;
 arr.length = 3;
I suppose this will allocate the array on the 'heap' or it's storage will last past the function scope doesn't it? What I want is to allocate such variable-length-array on the stack as any other local variable.
You can use alloca to get this effect: import core.stdc.stdlib: alloca; void main() { int s = 4; auto arr = (cast(float*)alloca(s))[0..s]; arr[] = 5; assert(arr == [5,5,5,5]); } It's not pretty, but it works.
Apr 13 2015
prev sibling parent reply Dmitri Makarov via Digitalmars-d <digitalmars-d puremagic.com> writes:
This should work the way you want it to:

void main()
{
   immutable size_t szArr = 3;

   int[szArr] arr;
}

Regards,

Dmitri


On Mon, Apr 13, 2015 at 7:05 PM, BS & LD via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Monday, 13 April 2015 at 17:02:13 UTC, CraigDillabaugh wrote:
 On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array using variably
 modified type and a run-time variable allocating a storage for it - the same
 way for any local (normally using the stack).

 However in 'D' I don't see such feature. Code like this fails:

 void main()
 {
    size_t szArr = 3;

    int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
     int[szArr] arr;

 Life example - http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf

 Note:  I'm also amazed why 'D' compiler can't detect that 'szArr' is a
 constant anyway.
This likely belongs in D.learn. What you are looking for is: int[] arr; arr.length = 3;
I suppose this will allocate the array on the 'heap' or it's storage will last past the function scope doesn't it? What I want is to allocate such variable-length-array on the stack as any other local variable.
Apr 13 2015
parent reply "Dylan Knutson" <tcdknutson gmail.com> writes:
On Monday, 13 April 2015 at 17:20:04 UTC, Dmitri Makarov wrote:
 This should work the way you want it to:

 void main()
 {
    immutable size_t szArr = 3;

    int[szArr] arr;
 }

 Regards,

 Dmitri
No, this isn't what VLA is. Ola Fosheim Grøstad has the right of it; he'll need to use alloca to dynamically extend the stack. What OP is referring to is the ability to create a dynamically sized array on the stack, rather than the heap. Here's a good description of what VLA is and how it works: https://en.wikipedia.org/wiki/Variable-length_array
Apr 13 2015
parent reply "Dmitri Makarov" <dmakarv gmail.com> writes:
On Monday, 13 April 2015 at 17:24:05 UTC, Dylan Knutson wrote:
 On Monday, 13 April 2015 at 17:20:04 UTC, Dmitri Makarov wrote:
 This should work the way you want it to:

 void main()
 {
   immutable size_t szArr = 3;

   int[szArr] arr;
 }

 Regards,

 Dmitri
No, this isn't what VLA is. Ola Fosheim Grøstad has the right of it; he'll need to use alloca to dynamically extend the stack. What OP is referring to is the ability to create a dynamically sized array on the stack, rather than the heap. Here's a good description of what VLA is and how it works: https://en.wikipedia.org/wiki/Variable-length_array
Ah, ok, then why did he complain that the compiler can't determine that the value of szArr is known at compile-time. A kind of conundrum, isn't it -- he want's to create arrays on stack with their sizes known at run-time, but wants the compiler to figure the size of such an array at compile-time...
Apr 13 2015
parent "BS & LD" <sasho648 gmail.com> writes:
On Monday, 13 April 2015 at 17:32:31 UTC, Dmitri Makarov wrote:
 On Monday, 13 April 2015 at 17:24:05 UTC, Dylan Knutson wrote:
 On Monday, 13 April 2015 at 17:20:04 UTC, Dmitri Makarov wrote:
 This should work the way you want it to:

 void main()
 {
  immutable size_t szArr = 3;

  int[szArr] arr;
 }

 Regards,

 Dmitri
No, this isn't what VLA is. Ola Fosheim Grøstad has the right of it; he'll need to use alloca to dynamically extend the stack. What OP is referring to is the ability to create a dynamically sized array on the stack, rather than the heap. Here's a good description of what VLA is and how it works: https://en.wikipedia.org/wiki/Variable-length_array
Ah, ok, then why did he complain that the compiler can't determine that the value of szArr is known at compile-time. A kind of conundrum, isn't it -- he want's to create arrays on stack with their sizes known at run-time, but wants the compiler to figure the size of such an array at compile-time...
Who wants the compiler creating un-efficient code? I supposed that I would need to write more complex code in order to fool it that 'szArr' isn't known at compile-time or even make it really so.
Apr 13 2015
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/13/15 12:53 PM, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array using variably
 modified type and a run-time variable allocating a storage for it - the
 same way for any local (normally using the stack).

 However in 'D' I don't see such feature. Code like this fails:

 void main()
 {
      size_t szArr = 3;

      int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
       int[szArr] arr;

 Life example - http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf
Note, it's best to show when comparing C/C++ to D the C++ code and how you expect it to work too. I experimented a bit with C++ to see what it will do: #include <stdio.h> int main(int argc, char *argv[]) { int arr[argc]; int i; printf("i: %p, arr[0]: %p\n", &i, &arr[0]); } Which makes the array completely variable size depending on argc (a runtime variable). The results surprised me a bit: $ ./testvararray i: 0x7fff5aeadb5c, arr[0]: 0x7fff5aeadb30 $ ./testvararray a i: 0x7fff5a955b4c, arr[0]: 0x7fff5a955b20 $ ./testvararray a b i: 0x7fff5854eb4c, arr[0]: 0x7fff5854eb20 $ ./testvararray a b c i: 0x7fff5fb12b3c, arr[0]: 0x7fff5fb12b10 $ ./testvararray a b c d i: 0x7fff528e1b2c, arr[0]: 0x7fff528e1af0 So the code will move i around depending on arr size. It's consistent between runs as well, if you pass the same number of args. I didn't expect that, but I wasn't sure exactly what I expected :) D doesn't do this, you have to know the size of the stack array at compile time. You can use alloca, which will give you some runtime allocation of stack, but it can be dangerous (as noted).
 Note:  I'm also amazed why 'D' compiler can't detect that 'szArr' is a
 constant anyway.
Value range propagation (the compiler understanding what values a variable can be at some point in time) only is inside one statement. It does not remember what szArr can be at a later statement. -Steve
Apr 13 2015
next sibling parent reply "BS & LD" <sasho648 gmail.com> writes:
On Monday, 13 April 2015 at 17:24:38 UTC, Steven Schveighoffer 
wrote:
 On 4/13/15 12:53 PM, BS & LD wrote:
 As you know in 'C' you can create a variable-length-array 
 using variably
 modified type and a run-time variable allocating a storage for 
 it - the
 same way for any local (normally using the stack).

 However in 'D' I don't see such feature. Code like this fails:

 void main()
 {
     size_t szArr = 3;

     int[szArr] arr;
 }

 With this error message:

 error: variable szArr cannot be read at compile time
      int[szArr] arr;

 Life example - 
 http://melpon.org/wandbox/permlink/a6CzBhYk88FohKlf
Note, it's best to show when comparing C/C++ to D the C++ code and how you expect it to work too. I experimented a bit with C++ to see what it will do: #include <stdio.h> int main(int argc, char *argv[]) { int arr[argc]; int i; printf("i: %p, arr[0]: %p\n", &i, &arr[0]); } Which makes the array completely variable size depending on argc (a runtime variable). The results surprised me a bit: $ ./testvararray i: 0x7fff5aeadb5c, arr[0]: 0x7fff5aeadb30 $ ./testvararray a i: 0x7fff5a955b4c, arr[0]: 0x7fff5a955b20 $ ./testvararray a b i: 0x7fff5854eb4c, arr[0]: 0x7fff5854eb20 $ ./testvararray a b c i: 0x7fff5fb12b3c, arr[0]: 0x7fff5fb12b10 $ ./testvararray a b c d i: 0x7fff528e1b2c, arr[0]: 0x7fff528e1af0 So the code will move i around depending on arr size. It's consistent between runs as well, if you pass the same number of args. I didn't expect that, but I wasn't sure exactly what I expected :) D doesn't do this, you have to know the size of the stack array at compile time. You can use alloca, which will give you some runtime allocation of stack, but it can be dangerous (as noted).
I don't know how things are handled here but it will be very nice if someone could make the language support this.
 Note:  I'm also amazed why 'D' compiler can't detect that 
 'szArr' is a
 constant anyway.
Value range propagation (the compiler understanding what values a variable can be at some point in time) only is inside one statement. It does not remember what szArr can be at a later statement. -Steve
Although I think it will be a nice feature if it can. I would prefer slower compilation then slower code.
Apr 13 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/13/15 1:34 PM, BS & LD wrote:
 On Monday, 13 April 2015 at 17:24:38 UTC, Steven Schveighoffer wrote:
 D doesn't do this, you have to know the size of the stack array at
 compile time. You can use alloca, which will give you some runtime
 allocation of stack, but it can be dangerous (as noted).
I don't know how things are handled here but it will be very nice if someone could make the language support this.
It's very unlikely this will make it into the language. Alloca should be good enough for this, it's not a very common usage, and supporting it is not easy.
 Value range propagation (the compiler understanding what values a
 variable can be at some point in time) only is inside one statement.
 It does not remember what szArr can be at a later statement.
Although I think it will be a nice feature if it can. I would prefer slower compilation then slower code.
It requires flow analysis, and that is not something I think any of the compiler devs are willing to add at this point. -Steve
Apr 13 2015
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 It's very unlikely this will make it into the language. Alloca 
 should be good enough for this, it's not a very common usage, 
 and supporting it is not easy.
alloca is bug-prone and unsafe, and if you want to create a 2D array on the stack it's not good enough. They are uncommonly used because they are not supported by the D compiler, and it doesn't track the memory ownership well enough. But a well designed system language needs to push programmers to use the stack as much as possible. Bye, bearophile
Apr 13 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/13/15 2:55 PM, bearophile wrote:
 Steven Schveighoffer:

 It's very unlikely this will make it into the language. Alloca should
 be good enough for this, it's not a very common usage, and supporting
 it is not easy.
alloca is bug-prone and unsafe, and if you want to create a 2D array on the stack it's not good enough. They are uncommonly used because they are not supported by the D compiler, and it doesn't track the memory ownership well enough. But a well designed system language needs to push programmers to use the stack as much as possible.
It would be nice if alloca could be wrapped so it could be made safe(r). -Steve
Apr 13 2015
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 13 April 2015 at 19:10:28 UTC, Steven Schveighoffer 
wrote:
 It would be nice if alloca could be wrapped so it could be made 
 safe(r).
string stackArray(T)(string name, string len) { import std.format : format; return q{ import core.stdc.stdlib : alloca; import std.conv : emplace; size_t %2$s_length_ = %3$s; %1$s* %2$s_storage_ = cast(%1$s*) alloca(%2$s_length_ * %1$s.sizeof); %1$s[] %2$s = %2$s_storage_[0 .. %2$s_length_]; foreach(ref ele; %2$s) emplace(&ele); }.format(T.stringof, name, len); } void main(string[] args) { import std.conv : to; import std.stdio : writefln; mixin(stackArray!int("arr", q{ args[1].to!size_t })); writefln("allocated an array of %s bytes", arr.length); writefln("arr = %s", arr); } This is the best I can come up with currently. I think with a forceinline attribute, it would be a lot better, assuming `alloca()` is usable inside an inlined method.
Apr 13 2015
parent reply Jacob Carlborg <doob me.com> writes:
On 2015-04-13 21:29, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" 
wrote:

 This is the best I can come up with currently. I think with a
  forceinline attribute, it would be a lot better, assuming `alloca()` is
 usable inside an inlined method.
If I recall correctly "alloca" can be used as a default argument to allocate on the caller stack [1]. If I'm correct and that's the case you shouldn't need to use string mixins? [1] http://forum.dlang.org/post/i1gql2$1k6o$1 digitalmars.com -- /Jacob Carlborg
Apr 14 2015
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Tuesday, 14 April 2015 at 08:28:23 UTC, Jacob Carlborg wrote:
 On 2015-04-13 21:29, "Marc =?UTF-8?B?U2Now7x0eiI=?= 
 <schuetzm gmx.net>" wrote:

 This is the best I can come up with currently. I think with a
  forceinline attribute, it would be a lot better, assuming 
 `alloca()` is
 usable inside an inlined method.
If I recall correctly "alloca" can be used as a default argument to allocate on the caller stack [1]. If I'm correct and that's the case you shouldn't need to use string mixins? [1] http://forum.dlang.org/post/i1gql2$1k6o$1 digitalmars.com
No. If alloca() ends up within a loop you are in a bad situation. Keep in mind that alloca is released on function RETURN. Not at the scope level. VLAs are released at scope level.
Apr 14 2015
parent reply Jacob Carlborg <doob me.com> writes:
On 2015-04-14 10:33, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= 
<ola.fosheim.grostad+dlang gmail.com>" wrote:

 No.
"No" as in "alloca" doesn't work like that for default arguments or a string mixin is still needed?
 If alloca() ends up within a loop you are in a bad situation. Keep
 in mind that alloca is released on function RETURN. Not at the scope
 level. VLAs are released at scope level.
Will the string mixin by Marc prevent that problem with loops? -- /Jacob Carlborg
Apr 14 2015
next sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Tuesday, 14 April 2015 at 08:52:19 UTC, Jacob Carlborg wrote:
 On 2015-04-14 10:33, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= 
 <ola.fosheim.grostad+dlang gmail.com>" wrote:

 No.
"No" as in "alloca" doesn't work like that for default arguments or a string mixin is still needed?
It does work like that, but I don't see a way to pass the length to the alloca() call. Unfortunately, we can't refer to other parameters. It that were possible, it would indeed work: import core.stdc.stdlib : alloca; T[] stackArray(T)(size_t len, T* p = cast(T*) alloca(len * T.sizeof)) { return p[0 .. len]; }
 If alloca() ends up within a loop you are in a bad situation. 
 Keep
 in mind that alloca is released on function RETURN. Not at the 
 scope
 level. VLAs are released at scope level.
Will the string mixin by Marc prevent that problem with loops?
No, that's an inherent problem with alloca(): there's no corresponding freea().
Apr 14 2015
parent reply Jacob Carlborg <doob me.com> writes:
On 2015-04-14 11:50, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" 
wrote:

 It does work like that, but I don't see a way to pass the length to the
 alloca() call. Unfortunately, we can't refer to other parameters. It
 that were possible, it would indeed work:

 import core.stdc.stdlib : alloca;
 T[] stackArray(T)(size_t len, T* p = cast(T*) alloca(len * T.sizeof)) {
          return p[0 .. len];
 }
Oh, I thought that would work. -- /Jacob Carlborg
Apr 14 2015
parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Tuesday, 14 April 2015 at 10:10:17 UTC, Jacob Carlborg wrote:
 On 2015-04-14 11:50, "Marc =?UTF-8?B?U2Now7x0eiI=?= 
 <schuetzm gmx.net>" wrote:

 It does work like that, but I don't see a way to pass the 
 length to the
 alloca() call. Unfortunately, we can't refer to other 
 parameters. It
 that were possible, it would indeed work:

 import core.stdc.stdlib : alloca;
 T[] stackArray(T)(size_t len, T* p = cast(T*) alloca(len * 
 T.sizeof)) {
         return p[0 .. len];
 }
Oh, I thought that would work.
Maybe that's worth an enhancement request? I agree with bearophile that stack local allocations should be encouraged more, and bare alloca() is unfortunately unsafe. With DIP25, it would even be possible to make a completely safe wrapper.
Apr 14 2015
prev sibling parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Tuesday, 14 April 2015 at 08:52:19 UTC, Jacob Carlborg wrote:
 On 2015-04-14 10:33, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= 
 <ola.fosheim.grostad+dlang gmail.com>" wrote:

 No.
"No" as in "alloca" doesn't work like that for default arguments or a string mixin is still needed?
I've got a feeling "alloca" is very close to "compiler implementation defined" so the safest thing is to treat it like a low level compiler optimization and do it explicitly in the top of a non-inlined function. I'm not even sure what happens in various D-compilers when they inline? Do they detect that there is an alloca there and create a "fake" stack frame for it or are they naive and repeatedly extend the stack frame inside loops when the functions inside the loops are inlined?
Apr 14 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Ola Fosheim Grøstad" " wrote in message 
news:ukkgvcqtidmgggprkcdf forum.dlang.org...

 I'm not even sure what happens in various D-compilers when they inline? Do 
 they detect that there is an alloca there and create a "fake" stack frame 
 for it or are they naive and repeatedly extend the stack frame inside 
 loops when the functions inside the loops are inlined?
DMD does not inline functions that have any calls to alloca.
Apr 14 2015
parent reply Jacob Carlborg <doob me.com> writes:
On 2015-04-14 16:28, Daniel Murphy wrote:

 DMD does not inline functions that have any calls to alloca.
What about this [1], is that something different? [1] https://github.com/D-Programming-Language/dmd/pull/3961 -- /Jacob Carlborg
Apr 15 2015
parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Jacob Carlborg"  wrote in message news:mglc1v$1d01$1 digitalmars.com...

 DMD does not inline functions that have any calls to alloca.
What about this [1], is that something different? [1] https://github.com/D-Programming-Language/dmd/pull/3961
Yes, that's because the inliner is used to copy the default argument expression to each call sight. DMD used to inline functions that called alloca, leading to stack overflows when the call was inside a loop, and when I fixed that it made the default arg 'inlining' of alloca calls regress.
Apr 15 2015
prev sibling parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Monday, 13 April 2015 at 17:24:38 UTC, Steven Schveighoffer 
wrote:
 Note, it's best to show when comparing C/C++ to D the C++ code 
 and how you expect it to work too.
Did you compile C++ with strict/pedantic options? ( I don't think it should work in compliant C++ )
Apr 13 2015
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 13 April 2015 at 17:51:27 UTC, Ola Fosheim Grøstad 
wrote:
 On Monday, 13 April 2015 at 17:24:38 UTC, Steven Schveighoffer 
 wrote:
 Note, it's best to show when comparing C/C++ to D the C++ code 
 and how you expect it to work too.
Did you compile C++ with strict/pedantic options? ( I don't think it should work in compliant C++ )
Dunno about C++, but IIRC VLAs are part of the C99 standard.
Apr 13 2015
parent "Paulo Pinto" <pjmlp progtools.org> writes:
On Monday, 13 April 2015 at 17:53:24 UTC, John Colvin wrote:
 On Monday, 13 April 2015 at 17:51:27 UTC, Ola Fosheim Grøstad 
 wrote:
 On Monday, 13 April 2015 at 17:24:38 UTC, Steven Schveighoffer 
 wrote:
 Note, it's best to show when comparing C/C++ to D the C++ 
 code and how you expect it to work too.
Did you compile C++ with strict/pedantic options? ( I don't think it should work in compliant C++ )
Dunno about C++, but IIRC VLAs are part of the C99 standard.
They were made optional in C11 due to the security risks and the emphasis in C11 to improve C's security. -- Paulo
Apr 13 2015
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/13/15 1:51 PM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 On Monday, 13 April 2015 at 17:24:38 UTC, Steven Schveighoffer wrote:
 Note, it's best to show when comparing C/C++ to D the C++ code and how
 you expect it to work too.
Did you compile C++ with strict/pedantic options? ( I don't think it should work in compliant C++ )
No, just g++ (and i believe this is clang) -Steve
Apr 13 2015
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Monday, 13 April 2015 at 17:56:57 UTC, Steven Schveighoffer 
wrote:
 No, just g++ (and i believe this is clang)

 -Steve
Clang tracks gcc, but it isn't C++ and therefore not portable: "Variable length arrays are not currently supported in Visual C++." https://msdn.microsoft.com/en-us/library/zb1574zs.aspx
Apr 13 2015