digitalmars.D - Does 'D' language supports 'C' like VLA?
- BS & LD (16/16) Apr 13 2015 As you know in 'C' you can create a variable-length-array using
- CraigDillabaugh (4/21) Apr 13 2015 This likely belongs in D.learn. What you are looking for is:
- John Colvin (4/32) Apr 13 2015 Eww.
- deadalnix (3/6) Apr 13 2015 IMO, that shouldn't be too difficult to promote that on stack if
- John Colvin (5/13) Apr 14 2015 The problem is that the size isn't necessarily known. I guess the
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (4/8) Apr 14 2015 C backends have alloca as a primitive:
- bearophile (9/13) Apr 14 2015 You don't forget to put branches added by the compiler, so it's
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (4/7) Apr 14 2015 VLAs can save stackspace compared to fixed max sized arrays, but
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (9/13) Apr 14 2015 To be clear: you get many of the same problems with fixed sized
- deadalnix (8/22) Apr 14 2015 The branch being way cheaper than an allocation anyway, and
- BS & LD (5/33) Apr 13 2015 I suppose this will allocate the array on the 'heap' or it's
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (2/37) Apr 13 2015 I suppose alloca will do it (somewhat unsafe?).
- CraigDillabaugh (3/38) Apr 13 2015 Yes, and as John pointed out it isn't the nicest way to do this.
- CraigDillabaugh (3/45) Apr 13 2015 I should mention that while it is on the heap, the storage should
- John Colvin (15/47) Apr 13 2015 It can, but allowing any variable that happens to be determined
- Dmitri Makarov via Digitalmars-d (10/46) Apr 13 2015 This should work the way you want it to:
- Dylan Knutson (7/15) Apr 13 2015 No, this isn't what VLA is. Ola Fosheim Grøstad has the right of
- Dmitri Makarov (6/25) Apr 13 2015 Ah, ok, then why did he complain that the compiler can't
- BS & LD (5/31) Apr 13 2015 Who wants the compiler creating un-efficient code? I supposed
- Steven Schveighoffer (33/48) Apr 13 2015 Note, it's best to show when comparing C/C++ to D the C++ code and how
- BS & LD (6/67) Apr 13 2015 I don't know how things are handled here but it will be very nice
- Steven Schveighoffer (7/19) Apr 13 2015 It's very unlikely this will make it into the language. Alloca should be...
- bearophile (9/12) Apr 13 2015 alloca is bug-prone and unsafe, and if you want to create a 2D
- Steven Schveighoffer (3/13) Apr 13 2015 It would be nice if alloca could be wrapped so it could be made safe(r).
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (26/28) Apr 13 2015 string stackArray(T)(string name, string len) {
- Jacob Carlborg (8/11) Apr 14 2015 If I recall correctly "alloca" can be used as a default argument to
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (4/14) Apr 14 2015 No. If alloca() ends up within a loop you are in a bad situation.
- Jacob Carlborg (7/11) Apr 14 2015 "No" as in "alloca" doesn't work like that for default arguments or a
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (11/22) Apr 14 2015 It does work like that, but I don't see a way to pass the length
- Jacob Carlborg (5/12) Apr 14 2015 Oh, I thought that would work.
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (5/19) Apr 14 2015 Maybe that's worth an enhancement request? I agree with
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (10/15) Apr 14 2015 I've got a feeling "alloca" is very close to "compiler
- Daniel Murphy (3/7) Apr 14 2015 DMD does not inline functions that have any calls to alloca.
- Jacob Carlborg (5/6) Apr 15 2015 What about this [1], is that something different?
- Daniel Murphy (5/8) Apr 15 2015 Yes, that's because the inliner is used to copy the default argument
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (4/6) Apr 13 2015 Did you compile C++ with strict/pedantic options?
- John Colvin (3/9) Apr 13 2015 Dunno about C++, but IIRC VLAs are part of the C99 standard.
- Paulo Pinto (5/16) Apr 13 2015 They were made optional in C11 due to the security risks and the
- Steven Schveighoffer (4/9) Apr 13 2015 No, just g++ (and i believe this is clang)
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (6/8) Apr 13 2015 Clang tracks gcc, but it isn't C++ and therefore not portable:
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
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
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:Eww. auto arr = new int[3]; Also, I think he's referring to something slightly different.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
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
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: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.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 14 2015
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-instructionI 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
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
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
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
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: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.On Monday, 13 April 2015 at 17:04:51 UTC, John Colvin wrote: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.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 14 2015
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: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.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
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:I suppose alloca will do it (somewhat unsafe?).On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote: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.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
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:Yes, and as John pointed out it isn't the nicest way to do this. Sorry for the noise.On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote: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.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
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:I should mention that while it is on the heap, the storage should get GC'd.On Monday, 13 April 2015 at 17:02:13 UTC, CraigDillabaugh wrote:Yes, and as John pointed out it isn't the nicest way to do this. Sorry for the noise.On Monday, 13 April 2015 at 16:53:55 UTC, BS & LD wrote: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.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
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: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.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.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.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
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: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.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
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, DmitriNo, 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
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: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...This should work the way you want it to: void main() { immutable size_t szArr = 3; int[szArr] arr; } Regards, DmitriNo, 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
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: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.On Monday, 13 April 2015 at 17:20:04 UTC, Dmitri Makarov wrote: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...This should work the way you want it to: void main() { immutable size_t szArr = 3; int[szArr] arr; } Regards, DmitriNo, 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
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/a6CzBhYk88FohKlfNote, 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
On Monday, 13 April 2015 at 17:24:38 UTC, Steven Schveighoffer wrote:On 4/13/15 12:53 PM, BS & LD wrote:I don't know how things are handled here but it will be very nice if someone could make the language support this.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/a6CzBhYk88FohKlfNote, 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).Although I think it will be a nice feature if it can. I would prefer slower compilation then slower code.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
On 4/13/15 1:34 PM, BS & LD wrote:On Monday, 13 April 2015 at 17:24:38 UTC, Steven Schveighoffer wrote: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.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 requires flow analysis, and that is not something I think any of the compiler devs are willing to add at this point. -SteveValue 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.
Apr 13 2015
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
On 4/13/15 2:55 PM, bearophile wrote:Steven Schveighoffer:It would be nice if alloca could be wrapped so it could be made safe(r). -SteveIt'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.
Apr 13 2015
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
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
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: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.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
Apr 14 2015
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
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: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]; }No."No" as in "alloca" doesn't work like that for default arguments or a string mixin is still needed?No, that's an inherent problem with alloca(): there's no corresponding freea().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?
Apr 14 2015
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
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: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.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.
Apr 14 2015
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: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?No."No" as in "alloca" doesn't work like that for default arguments or a string mixin is still needed?
Apr 14 2015
"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
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
"Jacob Carlborg" wrote in message news:mglc1v$1d01$1 digitalmars.com...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.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
Apr 15 2015
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
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:Dunno about C++, but IIRC VLAs are part of the C99 standard.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
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:They were made optional in C11 due to the security risks and the emphasis in C11 to improve C's security. -- PauloOn Monday, 13 April 2015 at 17:24:38 UTC, Steven Schveighoffer wrote:Dunno about C++, but IIRC VLAs are part of the C99 standard.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
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:No, just g++ (and i believe this is clang) -SteveNote, 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
On Monday, 13 April 2015 at 17:56:57 UTC, Steven Schveighoffer wrote:No, just g++ (and i believe this is clang) -SteveClang 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