digitalmars.D.learn - runtime static arrays
- Namespace (16/16) Nov 20 2012 Is there any need for 'smart' or 'compressed' arrays?
- bearophile (5/7) Nov 20 2012 Take also a look at the Array of Phobos.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (26/41) Nov 20 2012 The following program makes a slice from GC-allocated memory (or a
- Namespace (6/6) Nov 20 2012 Yes, but I could also use alloca. What I mean is the shortness of
- Namespace (8/8) Nov 20 2012 Something like:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (17/25) Nov 20 2012 This is a surprisingly promising start: :)
- Jonathan M Davis (14/46) Nov 20 2012 f the
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (3/6) Nov 20 2012 I know, I know... That surprising start surprised me too. :p
- bearophile (5/8) Nov 20 2012 See also:
- Jonathan M Davis (11/21) Nov 20 2012 It's pretty trivial to create a struct which uses malloc and free to cre...
- Namespace (2/19) Nov 20 2012 Yeah, but it's inconvenient to use a struct instead of a built in
- Jonathan M Davis (12/14) Nov 20 2012 But if the built-in solution doesn't do what you want, then that's what ...
- bearophile (50/55) Nov 20 2012 Variable Length Arrays are part of the standard in C since C99,
- Namespace (1/1) Nov 20 2012 Is there an official statement why Walter dislike them?
- bearophile (5/6) Nov 20 2012 In the last years I remember no comments from him about this
- Jonathan M Davis (10/15) Nov 20 2012 One serious problem posed by them is that the size then can't be part of...
- bearophile (11/23) Nov 20 2012 Take a look at my code, few posts above. When a VLA is passed to
- Timon Gehr (2/7) Nov 21 2012 It works as expected. A new GC-managed slice is created.
Is there any need for 'smart' or 'compressed' arrays? In my last projects I had some situations where I need an array, but only for one scope. But I could not use static arrays, because I didn't know the size at compile time. So I used 'alloca'. But 'alloca' has a terrible interface and in some few cases I had to append x elements. So I used a dynamic array. But dynamic arrays live longer as the lifetime of the scope. Furthermore dynamic arrays costs more memory as I needed, because the capacity of them is n * 2 + 1, but in my cases I need only n. So what I need was an array, which lives only for one scope (freed memory after leaving scope) and which hasn't more elements/capacity as I need. Am I wrong and dynamic arrays are the solution? Or is there need for such 'compressed' arrays? Another solution would be to improve the interface of alloca, but it would be still not resizable.
Nov 20 2012
Namespace:Furthermore dynamic arrays costs more memory as I needed,But maybe this doesn't happen in your case.Am I wrong and dynamic arrays are the solution?Take also a look at the Array of Phobos. Bye, bearophile
Nov 20 2012
On 11/20/2012 06:25 AM, Namespace wrote:Is there any need for 'smart' or 'compressed' arrays? In my last projects I had some situations where I need an array, but only for one scope. But I could not use static arrays, because I didn't know the size at compile time. So I used 'alloca'. But 'alloca' has a terrible interface and in some few cases I had to append x elements. So I used a dynamic array. But dynamic arrays live longer as the lifetime of the scope. Furthermore dynamic arrays costs more memory as I needed, because the capacity of them is n * 2 + 1, but in my cases I need only n. So what I need was an array, which lives only for one scope (freed memory after leaving scope) and which hasn't more elements/capacity as I need. Am I wrong and dynamic arrays are the solution? Or is there need for such 'compressed' arrays? Another solution would be to improve the interface of alloca, but it would be still not resizable.The following program makes a slice from GC-allocated memory (or a fixed-size array as in the comment). The important part is 'buffer[0..10]'. import std.stdio; import core.memory; void bar(int[] a) // Also try: int[10] a { writeln("param : ", a.ptr); } void foo() { int *buffer = cast(int*)GC.calloc(int.sizeof * 10); scope (exit) GC.free(buffer); writeln("buffer: ", buffer); int[] a = buffer[0..10]; // Also try: int[10] a = writeln("a : ", a.ptr); foreach (i; a) { i = 42 + i; } bar(a); } void main() { foo(); } Ali
Nov 20 2012
Yes, but I could also use alloca. What I mean is the shortness of int[4] arr or for (int i = 0; i < 42; i += 4) { int[i] arr; } I take a look at the std.container Array.
Nov 20 2012
Something like: scope int[8] arr; or scope int[i] arr; would be cool. You get an resizeable array which capactiy is all the time equal to his length. And it is destroyed after the liftetime of the scope. Maybe some stuff for Remus...
Nov 20 2012
On 11/20/2012 02:46 PM, Namespace wrote:Something like: scope int[8] arr; or scope int[i] arr; would be cool. You get an resizeable array which capactiy is all the time equal to his length. And it is destroyed after the liftetime of the scope. Maybe some stuff for Remus...This is a surprisingly promising start: :) import std.stdio; struct FixedArray(T, size_t N) { T[N] elements; alias elements this; } void main() { FixedArray!(int, 10) a; foreach (int i, ref e; a) { e = 42 + i; } writeln(a); } Ali
Nov 20 2012
On Tuesday, November 20, 2012 14:52:56 Ali =C3=87ehreli wrote:On 11/20/2012 02:46 PM, Namespace wrote:eSomething like: scope int[8] arr; or scope int[i] arr; =20 would be cool. You get an resizeable array which capactiy is all th=f thetime equal to his length. And it is destroyed after the liftetime o=How is that any different from just using a static array? All you've do= ne is=20 wrap it. You still can't set its size at runtime. Isn't what the OP is=20= essentially looking for is a static array whose length can be set at ru= ntime?=20 This doesn't solve that. For that, you need something which is going to= =20 allocate on the heap at runtime but deterministically free that that me= mory=20 when it's done. - Jonathan M Davisscope. =20 Maybe some stuff for Remus...=20 This is a surprisingly promising start: :) =20 import std.stdio; =20 struct FixedArray(T, size_t N) { T[N] elements; alias elements this; } =20 void main() { FixedArray!(int, 10) a; =20 foreach (int i, ref e; a) { e =3D 42 + i; } =20 writeln(a); }
Nov 20 2012
On 11/20/2012 02:59 PM, Jonathan M Davis wrote:On Tuesday, November 20, 2012 14:52:56 Ali Çehreli wrote:This is a surprisingly promising start: :)How is that any different from just using a static array?I know, I know... That surprising start surprised me too. :p Ali
Nov 20 2012
Namespace:scope int[8] arr; or scope int[i] arr;See also: http://d.puremagic.com/issues/show_bug.cgi?id=5348 Bye, bearophile
Nov 20 2012
On Tuesday, November 20, 2012 23:46:39 Namespace wrote:Something like: scope int[8] arr; or scope int[i] arr; would be cool. You get an resizeable array which capactiy is all the time equal to his length. And it is destroyed after the liftetime of the scope. Maybe some stuff for Remus...It's pretty trivial to create a struct which uses malloc and free to create a dynamic array of the exact size that you want with deterministic destruction, and you can easily overload the indexing and slicing operators - though clearly, as if with static arrays, you'd have to be careful with slices being passed around, since they're not owned by the GC. And I'm not sure what would happen if you were foolish enough to try and append to them. Personally though, I wish that the length of static arrays could be set at runtime and don't really understand why you can't (aside from the fact that you can't in standard C - gcc will let you though). - Jonathan M Davis
Nov 20 2012
It's pretty trivial to create a struct which uses malloc and free to create a dynamic array of the exact size that you want with deterministic destruction, and you can easily overload the indexing and slicing operators - though clearly, as if with static arrays, you'd have to be careful with slices being passed around, since they're not owned by the GC. And I'm not sure what would happen if you were foolish enough to try and append to them. Personally though, I wish that the length of static arrays could be set at runtime and don't really understand why you can't (aside from the fact that you can't in standard C - gcc will let you though). - Jonathan M DavisYeah, but it's inconvenient to use a struct instead of a built in solution. ;)
Nov 20 2012
On Wednesday, November 21, 2012 00:30:16 Namespace wrote:Yeah, but it's inconvenient to use a struct instead of a built in solution. ;)But if the built-in solution doesn't do what you want, then that's what you have to do. And the only built-in solutions are to either have a static array where you know its length at compile time or to use dynamic arrays, whose memory would be managed by the GC and which would allocate extra memory beyond the end of the array in order to make appending efficient. If either of those are fine, then there you go. But if they're not fine, then you need to find another solution. std.container.Array is closer to what you seem to want, but it would also allocate extra memory (it should have deterministic destruction though, since it uses malloc and free internally). To do exactly what you want would require creating your own type. - Jonathan M Davis
Nov 20 2012
Jonathan M Davis:Personally though, I wish that the length of static arrays could be set at runtime and don't really understand why you can't (aside from the fact that you can't in standard C - gcc will let you though).Variable Length Arrays are part of the standard in C since C99, and they are in C11 still. D doesn't have VLAs, I have asked for them since lot of time. I don't know why Walter doesn't like them. After using Ada language a little, I believe that stack allocation is very useful when you want to write fast code. VLAs are a little unsafe in D because they are not on the heap, but a good type system is able to make them safe (some kind of static region analysis, done by the Rust language compiler, not present in D). Beside the problem of memory ownership, and problems with stack overflows, there are other problems with VLAs, like how the D type system has to denote them, and how to move them around. How do you return them? Some considerations: void foo(int n) { int[](n) data; // D VLA syntax? static assert(sizeof(data) = sizeof(size_t)); // 1 word? static assert(is(typeof(data) == int())); bar(data); // OK, decays to dynamic array bar(data.dup); // OK, dup turns it on a heap allocated dynamic array spam(data); // probably not allowed. } void bar(int[] a) {} void spam(int[10] b) {} void baz(int() c) {} // not allowed syntax. Here I have used a different syntax because I think there is a problem with using the normal syntax: D performs CTFE when you call a function in a context that asks for a compile-time result value. Currently static array definitions require a compile-time value, so they induce CTFE. If D gains VLAs stack arrays can be created with a run-time size too, so how does the compiler knows if you want CTFE and to create a fixed array or you want to call the function at runtime and create a VLA? A different syntax avoids this problem. VLAs are meant only for automatic variables, you can't put one of them in structs or class instances, or in global scope. Also a VLA decades in a dynamic array with dup or to fixed size whem given to a function with fixed sized argument, so you can't pass VLA around. One advantage of VLA is a less bug-prone syntax compared to alloca(), expecially when you want 2D, 3D, etc VLA array. C++11 has not introduced VLA for unclear reasons, but probably one reason was to not add more complexities. In the D type system there are dynamic arrays, so the situation is better. Maybe some kind of VLAs will be present in C++14, according to what the C++ committee says. Bye, bearophile
Nov 20 2012
Is there an official statement why Walter dislike them?
Nov 20 2012
Namespace:Is there an official statement why Walter dislike them?In the last years I remember no comments from him about this topic. But he has not closed my enhancement request. Bye, bearophile
Nov 20 2012
On Wednesday, November 21, 2012 02:26:35 bearophile wrote:Namespace:One serious problem posed by them is that the size then can't be part of the type, meaning that you can't possibly pass them around. If you did, you'd just be passing dynamic arrays around. You'd have the same problem with them with templates - everything instantiated with them would have to be instantiated as a dynamic array, which could cause problems. So, while in principle, I like the idea of being able to have the size of a static array determined when it's created, there are definitely problems with doing that once you start getting into the details of what that would mean. - Jonathan M DavisIs there an official statement why Walter dislike them?In the last years I remember no comments from him about this topic. But he has not closed my enhancement request.
Nov 20 2012
Jonathan M Davis:One serious problem posed by them is that the size then can't be part of the type, meaning that you can't possibly pass them around. If you did, you'd just be passing dynamic arrays around.Take a look at my code, few posts above. When a VLA is passed to a function, it "decays" to a dynamic array.You'd have the same problem with them with templates - everything instantiated with them would have to be instantiated as a dynamic array, which could cause problems.Templates will support arrays, they already do partially. Kind of arrays and templates are two orthogonal things. What matters for templates is the a value is known at compile time or not. So I think this is not a problem.there are definitely problems with doing that once you start getting into the details of what that would mean.I agree there are some problems. But I think they aren't hard problems to solve. Bye, bearophile
Nov 20 2012
On 11/20/2012 11:56 PM, Jonathan M Davis wrote:... clearly, as if with static arrays, you'd have to be careful with slices being passed around, since they're not owned by the GC. And I'm not sure what would happen if you were foolish enough to try and append to them. ...It works as expected. A new GC-managed slice is created.
Nov 21 2012