digitalmars.D - no macros in D?
- Maxime Larose (26/26) May 04 2005 I'm I missing something or is there no way to have true macros in D? Th...
- Andrew Fedoniouk (20/47) May 04 2005 Maxime,
- Vathix (16/34) May 04 2005 Beat me to it :p
- Andrew Fedoniouk (10/48) May 04 2005 Oh, yeh :)))
- Maxime Larose (12/84) May 04 2005 This variant is not really re-useable because the variable name is fixed...
- Andrew Fedoniouk (19/121) May 04 2005 What about this:
- Chris Sauls (8/19) May 05 2005 It is in the docs... see ( http://www.digitalmars.com/d/mixin.html ) in
- Uwe Salomon (9/13) May 04 2005 Uh. Isn't that better? :
- Uwe Salomon (41/41) May 04 2005 It is not that simple, because alloca() allocates on the stack of the
- Ben Hinkle (11/14) May 04 2005 [snip]
- Sean Kelly (4/6) May 04 2005 Mixins are about as close as you can get. Why not use plain old functio...
- Maxime Larose (9/16) May 04 2005 In debug mode, that would simply crash... I.e. the "stack" allocated
- Sean Kelly (3/24) May 04 2005 I'd forgotten you were doing stack allocations :p What about a memory m...
- Russ Lewis (7/49) May 04 2005 How about
- Maxime Larose (8/57) May 04 2005 This will create an arrray in the heap, not on the stack. (That's a main
- Russ Lewis (13/85) May 04 2005 I'm pretty sure that this is not correct. Fixed-length arrays are
- Sean Kelly (5/14) May 04 2005 I don't think this is true. Static arrays should be allocated on the st...
- Maxime Larose (9/26) May 04 2005 Reading the section on memory management, I really got the feeling that
- Kramer (5/63) May 04 2005 Is that bad? Would that cause performance problems? I'm guessing the a...
- Walter (3/5) May 04 2005 No, it'll be on the stack just like in C/C++.
- Maxime Larose (8/13) May 05 2005 Then, how are arrays returned? Is't not safe to return a char[] from a
- Chris Sauls (8/14) May 05 2005 Dynamic arrays (such as char[]) are on the heap, so may be freely
- Maxime Larose (15/29) May 05 2005 I
- Vladimir (8/46) May 05 2005 Array can't be returned, only reference i.e. dynamic array.
- Vladimir (22/39) May 05 2005 Function can't return static arrays, only dynamic.
- Benji Smith (8/27) May 05 2005 That's insane.
- Ben Hinkle (6/35) May 05 2005 The D spec http://www.digitalmars.com/d/function.html section Local
- Benji Smith (8/12) May 05 2005 So this code should produce an error?
- Ben Hinkle (11/23) May 05 2005 yes - the initializer "string" is copied onto the stack space for myStri...
- Benji Smith (8/13) May 05 2005 I don't think the compiler should *copy* data from the stack to the
- Russ Lewis (7/23) May 05 2005 One problem here is that this will lead to inconsitent behavior of the
- Maxime Larose (18/58) May 05 2005 Hmmm..... No wonder I was messed up. All of this is *extremely* error-pr...
- Sean Kelly (21/29) May 05 2005 This would be nice, but the C++ compilers I've used don't typically erro...
- Maxime Larose (51/81) May 05 2005 (The problem here is solely with arrays. All other return values (ints,
- Benji Smith (11/15) May 05 2005 Sean, would you mind elaborating on this a little bit?
- Russ Lewis (22/36) May 05 2005 I think the thing that both you and Maxime are missing is the concept of...
- Ben Hinkle (10/17) May 05 2005 umm - a dyanmic array can point to the stack. That's what happens with
- Russ Lewis (2/10) May 05 2005 True, of course. I was being overliy simplistic :/
- Sean Kelly (16/30) May 05 2005 Perhaps it's because I'm so accustomed to C++, but I don't see any reaso...
- Russ Lewis (8/14) May 05 2005 This is not correct. If you assign a static array to a dynamic array
I'm I missing something or is there no way to have true macros in D? The facilities to generate boiler plate code doesn't seem to go far enough. For instance, I want to define an alias/template/mixin/whatever for simplifying the syntax to create stuff on the stack. Here is how the code would look ideally: void main() { char[] abc = stack_char(1000); } stack_char being a specialization of a stack_array!(T) or something like that. I tried a thousand variations with mixins, templates and aliases, the compiler is always complaining one way or the other. And when it works, a function is called (defeating the purpose of creating the variable in the local stack). Even doing something very simply like: alias cast(char*)std.c.stdlib.alloca stack_char; doesn't work. The compiler complains about the (char*). Less ideally, I thought of doing: stack_array(abc, char, 1000); which would expand to: char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000] This seems simple enough. However, it doesn't work because "abc" is not defined prior to use. (Even when I use an "alias" parameter for the template.) I'm I missing something? This seems like very simple stuff...
May 04 2005
Maxime, could you check your code again? Following just works: ---------------------------------- import std.stdio; import std.c.stdlib; template stackArray(T, uint N) { char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N]; } int main(char[][] args) { mixin stackArray!(char,1000); v[0] = 'h'; writef("%d\n", v.length ); return 0; } ----------------------------------- "Maxime Larose" <mlarose broadsoft.com> wrote in message news:d5apgr$279m$1 digitaldaemon.com...I'm I missing something or is there no way to have true macros in D? The facilities to generate boiler plate code doesn't seem to go far enough. For instance, I want to define an alias/template/mixin/whatever for simplifying the syntax to create stuff on the stack. Here is how the code would look ideally: void main() { char[] abc = stack_char(1000); } stack_char being a specialization of a stack_array!(T) or something like that. I tried a thousand variations with mixins, templates and aliases, the compiler is always complaining one way or the other. And when it works, a function is called (defeating the purpose of creating the variable in the local stack). Even doing something very simply like: alias cast(char*)std.c.stdlib.alloca stack_char; doesn't work. The compiler complains about the (char*). Less ideally, I thought of doing: stack_array(abc, char, 1000); which would expand to: char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000] This seems simple enough. However, it doesn't work because "abc" is not defined prior to use. (Even when I use an "alias" parameter for the template.) I'm I missing something? This seems like very simple stuff...
May 04 2005
On Wed, 04 May 2005 11:41:23 -0400, Andrew Fedoniouk <news terrainformatica.com> wrote:Maxime, could you check your code again? Following just works: ---------------------------------- import std.stdio; import std.c.stdlib; template stackArray(T, uint N) { char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N]; } int main(char[][] args) { mixin stackArray!(char,1000); v[0] = 'h'; writef("%d\n", v.length ); return 0; } -----------------------------------Beat me to it :p private import std.c.stdlib, std.stdio; template stack_array(T, size_t count) { T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 .. count]; } int main() { mixin stack_array!(char, 500) abc; abc.value[0 .. 500] = 'f'; writefln("The length is %d", abc.value.length); writefln("The answer is '%s'", abc.value); return 0; }
May 04 2005
Oh, yeh :))) Thanks a lot. As always with concept cars they can move in theory but in practice only on podium. That was just such a car. Quick and ugly. Beg my pardon, Uwe, thanks you too. Andrew. "Vathix" <vathix dprogramming.com> wrote in message news:op.sp9cntpqkcck4r esi...On Wed, 04 May 2005 11:41:23 -0400, Andrew Fedoniouk <news terrainformatica.com> wrote:Maxime, could you check your code again? Following just works: ---------------------------------- import std.stdio; import std.c.stdlib; template stackArray(T, uint N) { char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N]; } int main(char[][] args) { mixin stackArray!(char,1000); v[0] = 'h'; writef("%d\n", v.length ); return 0; } -----------------------------------Beat me to it :p private import std.c.stdlib, std.stdio; template stack_array(T, size_t count) { T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 .. count]; } int main() { mixin stack_array!(char, 500) abc; abc.value[0 .. 500] = 'f'; writefln("The length is %d", abc.value.length); writefln("The answer is '%s'", abc.value); return 0; }
May 04 2005
This variant is not really re-useable because the variable name is fixed, i.e. "v". It prevents you from having many such variables in the same function (or forces you to define many different templates...) (I had tried it)template stackArray(T, uint N) { char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N]; }This variant is good and generally useable. I didn't try it, because I didn't know it was possible to put the name of a variable after the mixin... It's not in the doc at any rate and not really intuitive (IMO). But if it works... ;) All right, thanks. I'll try it out tonight. Max "Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:d5ariq$29j2$1 digitaldaemon.com...template stack_array(T, size_t count) { T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 .. count]; } int main() { mixin stack_array!(char, 500) abc; abc.value[0 .. 500] = 'f';Oh, yeh :))) Thanks a lot. As always with concept cars they can move in theory but in practice only on podium. That was just such a car. Quick and ugly. Beg my pardon, Uwe, thanks you too. Andrew. "Vathix" <vathix dprogramming.com> wrote in message news:op.sp9cntpqkcck4r esi...On Wed, 04 May 2005 11:41:23 -0400, Andrew Fedoniouk <news terrainformatica.com> wrote:Maxime, could you check your code again? Following just works: ---------------------------------- import std.stdio; import std.c.stdlib; template stackArray(T, uint N) { char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N]; } int main(char[][] args) { mixin stackArray!(char,1000); v[0] = 'h'; writef("%d\n", v.length ); return 0; } -----------------------------------Beat me to it :p private import std.c.stdlib, std.stdio; template stack_array(T, size_t count) { T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 .. count]; } int main() { mixin stack_array!(char, 500) abc; abc.value[0 .. 500] = 'f'; writefln("The length is %d", abc.value.length); writefln("The answer is '%s'", abc.value); return 0; }
May 04 2005
This variant is not really re-useable because the variable name is fixed, i.e. "v". It prevents you from having many such variables in the same function (or forces you to define many different templates...) (I had tried it)What about this: import std.stdio; import std.c.stdlib; template stackArray(T, uint N) { char[] elements = (cast(T*)std.c.stdlib.alloca(N*T.sizeof))[0..N]; } int main(char[][] args) { mixin stackArray!(char,1000) one; mixin stackArray!(char,2000) two; one.elements[0] = 'h'; two.elements[0] = 'h'; writef("%d\n", one.elements.length ); writef("%d\n", two.elements.length ); return 0; } "Maxime Larose" <mlarose broadsoft.com> wrote in message news:d5atv3$2c3j$1 digitaldaemon.com...This variant is not really re-useable because the variable name is fixed, i.e. "v". It prevents you from having many such variables in the same function (or forces you to define many different templates...) (I had tried it)template stackArray(T, uint N) { char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N]; }This variant is good and generally useable. I didn't try it, because I didn't know it was possible to put the name of a variable after the mixin... It's not in the doc at any rate and not really intuitive (IMO). But if it works... ;) All right, thanks. I'll try it out tonight. Max "Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:d5ariq$29j2$1 digitaldaemon.com...template stack_array(T, size_t count) { T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 .. count]; } int main() { mixin stack_array!(char, 500) abc; abc.value[0 .. 500] = 'f';Oh, yeh :))) Thanks a lot. As always with concept cars they can move in theory but in practice only on podium. That was just such a car. Quick and ugly. Beg my pardon, Uwe, thanks you too. Andrew. "Vathix" <vathix dprogramming.com> wrote in message news:op.sp9cntpqkcck4r esi...On Wed, 04 May 2005 11:41:23 -0400, Andrew Fedoniouk <news terrainformatica.com> wrote:Maxime, could you check your code again? Following just works: ---------------------------------- import std.stdio; import std.c.stdlib; template stackArray(T, uint N) { char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N]; } int main(char[][] args) { mixin stackArray!(char,1000); v[0] = 'h'; writef("%d\n", v.length ); return 0; } -----------------------------------Beat me to it :p private import std.c.stdlib, std.stdio; template stack_array(T, size_t count) { T[] value = (cast(T*)std.c.stdlib.alloca(count * T.sizeof))[0 .. count]; } int main() { mixin stack_array!(char, 500) abc; abc.value[0 .. 500] = 'f'; writefln("The length is %d", abc.value.length); writefln("The answer is '%s'", abc.value); return 0; }
May 04 2005
Maxime Larose wrote:This variant is good and generally useable. I didn't try it, because I didn't know it was possible to put the name of a variable after the mixin... It's not in the doc at any rate and not really intuitive (IMO). But if it works... ;)It is in the docs... see ( http://www.digitalmars.com/d/mixin.html ) in two places. Once at the beginning where the mixin grammar is given as:TemplateMixin: mixin TemplateIdentifier ; mixin TemplateIdentifier MixinIdentifier ; mixin TemplateIdentifier !( TemplateArgumentList ) ; mixin TemplateIdentifier !( TemplateArgumentList ) MixinIdentifier ; MixinIdentifier: IdentifierAnd again fairly near the end, where it says "If a mixin has a MixinIdentifier, it can be used to disambiguate" and then gives an example. I know its easy to miss some things in the docs... all kinds of hidden treasures in there if one gets out the proverbial fine-toothed comb. -- Chris Sauls
May 05 2005
template stackArray(T, uint N) { char[] v = (cast(T*)std.c.stdlib.alloca(N))[0..N]; }Uh. Isn't that better? : template stackArray(T, size_t N) { T[] vec = (cast(T*) std.c.stdlib.alloca(N * T.sizeof))[0 .. N]; } And some specialization for N*T.sizeof > xxx bytes would do some good, to... Ciao uwe
May 04 2005
It is not that simple, because alloca() allocates on the stack of the called function, thus you cannot insert it into a sub-function (if it returns, the allocated space is gone). You have to write a little more sophisticated template like QVarLengthArray from Qt 4.0 (should be at http://doc.trolltech.com/4.0/qvarlengtharray.html). When i have finished indigo.string (a QString lookalike), i will perhaps work on that. Just to give you a hint: struct VarLengthArray(T, size_t stackSize) { private: T[stackSize] m_stackData; public: T[] data(size_t neededSize) { if (neededSize <= stackSize) return m_stackData[0 .. neededSize]; else return new T[neededSize]; } } Well, this is really a simple algorithm, but it shows the principle quite well. You allocate a fixed size on the stack, and if that's not enough, you take from the heap. You can use that like this: void myFunc(int someParam, size_t elemCountToWorkWith) { VarLengthArray!(uint, 256) stackArray; uint[] vec = stackArray.data(elemCountToWorkWith); // Do something with vec... foreach (uint x; vec) // ... } Here you have a function that has to do something with a certain number of uint's, which will be less than 256 in 90% of the cases (or whatever percentage you need). If elemCountToWorkWith is under 256, this array will be allocated on the stack (very fast), otherwise on the heap. If you call this function often, this will make a significant speed improvement (and of course create less garbage). But i do not know how much faster/slower than alloca() this variant is (at least it does not safe you some typing. :) Ciao uwe
May 04 2005
"Maxime Larose" <mlarose broadsoft.com> wrote in message news:d5apgr$279m$1 digitaldaemon.com...I'm I missing something or is there no way to have true macros in D? The facilities to generate boiler plate code doesn't seem to go far enough.[snip]char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000]It would be nice if placement worked for char[]s: char[] abc = new(alloca(1000))char[1000]; From my experiments the line above compiles but it looks like it winds up allocating from the GC. Note in the example about alloca it would be nice if the "std.c.stdlib" were removed since it makes the code look nastier than it has to be. I suppose it tells the reader that alloca is in std.c.stdlib but it gives the impression it should always be used when allocating from the stack.
May 04 2005
In article <d5apgr$279m$1 digitaldaemon.com>, Maxime Larose says...I'm I missing something or is there no way to have true macros in D? The facilities to generate boiler plate code doesn't seem to go far enough.Mixins are about as close as you can get. Why not use plain old functions and compile with -inline? That should address performance concerns in most cases. Sean
May 04 2005
In debug mode, that would simply crash... I.e. the "stack" allocated variable would be allocated on the stack of the callee, not the caller. Inlining only partially solves the problem in that you are never sure of what gets inlined and what does not. It leads to non-portable code at its worst. "Sean Kelly" <sean f4.ca> wrote in message news:d5asqh$2arf$1 digitaldaemon.com...In article <d5apgr$279m$1 digitaldaemon.com>, Maxime Larose says...andI'm I missing something or is there no way to have true macros in D? The facilities to generate boiler plate code doesn't seem to go far enough.Mixins are about as close as you can get. Why not use plain old functionscompile with -inline? That should address performance concerns in mostcases.Sean
May 04 2005
I'd forgotten you were doing stack allocations :p What about a memory manager that uses a static array of ubyte as a memory pool? In article <d5b0d5$2en9$1 digitaldaemon.com>, Maxime Larose says...In debug mode, that would simply crash... I.e. the "stack" allocated variable would be allocated on the stack of the callee, not the caller. Inlining only partially solves the problem in that you are never sure of what gets inlined and what does not. It leads to non-portable code at its worst. "Sean Kelly" <sean f4.ca> wrote in message news:d5asqh$2arf$1 digitaldaemon.com...In article <d5apgr$279m$1 digitaldaemon.com>, Maxime Larose says...andI'm I missing something or is there no way to have true macros in D? The facilities to generate boiler plate code doesn't seem to go far enough.Mixins are about as close as you can get. Why not use plain old functionscompile with -inline? That should address performance concerns in mostcases.Sean
May 04 2005
How about void main() { char[1000] abc; } ? Maxime Larose wrote:I'm I missing something or is there no way to have true macros in D? The facilities to generate boiler plate code doesn't seem to go far enough. For instance, I want to define an alias/template/mixin/whatever for simplifying the syntax to create stuff on the stack. Here is how the code would look ideally: void main() { char[] abc = stack_char(1000); } stack_char being a specialization of a stack_array!(T) or something like that. I tried a thousand variations with mixins, templates and aliases, the compiler is always complaining one way or the other. And when it works, a function is called (defeating the purpose of creating the variable in the local stack). Even doing something very simply like: alias cast(char*)std.c.stdlib.alloca stack_char; doesn't work. The compiler complains about the (char*). Less ideally, I thought of doing: stack_array(abc, char, 1000); which would expand to: char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000] This seems simple enough. However, it doesn't work because "abc" is not defined prior to use. (Even when I use an "alias" parameter for the template.) I'm I missing something? This seems like very simple stuff...
May 04 2005
This will create an arrray in the heap, not on the stack. (That's a main difference between C(++) and D) "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:d5b42s$2hns$1 digitaldaemon.com...How about void main() { char[1000] abc; } ? Maxime Larose wrote:TheI'm I missing something or is there no way to have true macros in D?codefacilities to generate boiler plate code doesn't seem to go far enough. For instance, I want to define an alias/template/mixin/whatever for simplifying the syntax to create stuff on the stack. Here is how theawould look ideally: void main() { char[] abc = stack_char(1000); } stack_char being a specialization of a stack_array!(T) or something like that. I tried a thousand variations with mixins, templates and aliases, the compiler is always complaining one way or the other. And when it works,thefunction is called (defeating the purpose of creating the variable inlocal stack). Even doing something very simply like: alias cast(char*)std.c.stdlib.alloca stack_char; doesn't work. The compiler complains about the (char*). Less ideally, I thought of doing: stack_array(abc, char, 1000); which would expand to: char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000] This seems simple enough. However, it doesn't work because "abc" is not defined prior to use. (Even when I use an "alias" parameter for the template.) I'm I missing something? This seems like very simple stuff...
May 04 2005
I'm pretty sure that this is not correct. Fixed-length arrays are created on the stack. Dynamic arrays, of course, are on the heap. Try running this program: import std.stdio; void main() { int i; char[1000] abc; int j; writefln("&i=%d &abc=%d &abc[0]=%d &j=%d\n", &i,&abc,&abc[0],&j); } I get: &i=bffff458 &abc=bffff45c &abc[0]=bffff45c &j=bffff844 Maxime Larose wrote:This will create an arrray in the heap, not on the stack. (That's a main difference between C(++) and D) "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:d5b42s$2hns$1 digitaldaemon.com...How about void main() { char[1000] abc; } ? Maxime Larose wrote:TheI'm I missing something or is there no way to have true macros in D?codefacilities to generate boiler plate code doesn't seem to go far enough. For instance, I want to define an alias/template/mixin/whatever for simplifying the syntax to create stuff on the stack. Here is how theawould look ideally: void main() { char[] abc = stack_char(1000); } stack_char being a specialization of a stack_array!(T) or something like that. I tried a thousand variations with mixins, templates and aliases, the compiler is always complaining one way or the other. And when it works,thefunction is called (defeating the purpose of creating the variable inlocal stack). Even doing something very simply like: alias cast(char*)std.c.stdlib.alloca stack_char; doesn't work. The compiler complains about the (char*). Less ideally, I thought of doing: stack_array(abc, char, 1000); which would expand to: char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000] This seems simple enough. However, it doesn't work because "abc" is not defined prior to use. (Even when I use an "alias" parameter for the template.) I'm I missing something? This seems like very simple stuff...
May 04 2005
I don't think this is true. Static arrays should be allocated on the stack just as in C. The page on arrays and the page on memory management seem to confirm this. The only catch is that this syntax *will* zero out the array contents, which may be undesirable from a performance perspective. In article <d5b9dl$2n39$1 digitaldaemon.com>, Maxime Larose says...This will create an arrray in the heap, not on the stack. (That's a main difference between C(++) and D) "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:d5b42s$2hns$1 digitaldaemon.com...How about void main() { char[1000] abc; }
May 04 2005
Reading the section on memory management, I really got the feeling that arrays were created on the heap... I got confused with classes apparently. Very sorry to have wasted your time... (Though I'm glad I now know the "mixin template!(T) var" way of using mixins...) "Sean Kelly" <sean f4.ca> wrote in message news:d5bakl$2oau$1 digitaldaemon.com...I don't think this is true. Static arrays should be allocated on thestack justas in C. The page on arrays and the page on memory management seem toconfirmthis. The only catch is that this syntax *will* zero out the arraycontents,which may be undesirable from a performance perspective. In article <d5b9dl$2n39$1 digitaldaemon.com>, Maxime Larose says...This will create an arrray in the heap, not on the stack. (That's a main difference between C(++) and D) "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:d5b42s$2hns$1 digitaldaemon.com...How about void main() { char[1000] abc; }
May 04 2005
In article <d5b9dl$2n39$1 digitaldaemon.com>, Maxime Larose says...This will create an arrray in the heap, not on the stack. (That's a main difference between C(++) and D)Is that bad? Would that cause performance problems? I'm guessing the answers to these questions are it depends (what application domain?; what's bad?) Is that a fundamental shift from other languages? -Kramer"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:d5b42s$2hns$1 digitaldaemon.com...How about void main() { char[1000] abc; } ? Maxime Larose wrote:TheI'm I missing something or is there no way to have true macros in D?codefacilities to generate boiler plate code doesn't seem to go far enough. For instance, I want to define an alias/template/mixin/whatever for simplifying the syntax to create stuff on the stack. Here is how theawould look ideally: void main() { char[] abc = stack_char(1000); } stack_char being a specialization of a stack_array!(T) or something like that. I tried a thousand variations with mixins, templates and aliases, the compiler is always complaining one way or the other. And when it works,thefunction is called (defeating the purpose of creating the variable inlocal stack). Even doing something very simply like: alias cast(char*)std.c.stdlib.alloca stack_char; doesn't work. The compiler complains about the (char*). Less ideally, I thought of doing: stack_array(abc, char, 1000); which would expand to: char[] abc = (cast(char*)std.c.stdlib.alloca(1000))[0..1000] This seems simple enough. However, it doesn't work because "abc" is not defined prior to use. (Even when I use an "alias" parameter for the template.) I'm I missing something? This seems like very simple stuff...
May 04 2005
"Maxime Larose" <mlarose broadsoft.com> wrote in message news:d5b9dl$2n39$1 digitaldaemon.com...This will create an arrray in the heap, not on the stack. (That's a main difference between C(++) and D)No, it'll be on the stack just like in C/C++.
May 04 2005
Then, how are arrays returned? Is't not safe to return a char[] from a function if it's allocated on the stack?!? I must have been messed up really good then, because as a GC'ed language I assumed one was free to return a string (char[]) from a function. I *think* I even already did it, but I may be mistaken (or I was just very luck that the stack didn't get corrupted)... "Walter" <newshound digitalmars.com> wrote in message news:d5bc2t$2pca$1 digitaldaemon.com..."Maxime Larose" <mlarose broadsoft.com> wrote in message news:d5b9dl$2n39$1 digitaldaemon.com...This will create an arrray in the heap, not on the stack. (That's a main difference between C(++) and D)No, it'll be on the stack just like in C/C++.
May 05 2005
Maxime Larose wrote:Then, how are arrays returned? Is't not safe to return a char[] from a function if it's allocated on the stack?!? I must have been messed up really good then, because as a GC'ed language I assumed one was free to return a string (char[]) from a function. I *think* I even already did it, but I may be mistaken (or I was just very luck that the stack didn't get corrupted)...Dynamic arrays (such as char[]) are on the heap, so may be freely returned. I assume that if one returns a static array (such as char[256]) then a copy would be made. Of course, you could define a function as returning a dynamic array, and still return the value of a static array. As I understand it, its data is copied to a new dynamic array, and a referance to the anonymous dynamic array is returned. -- Chris Sauls
May 05 2005
"Chris Sauls" <ibisbasenji gmail.com> wrote in message news:d5csgj$sha$1 digitaldaemon.com...Maxime Larose wrote:IThen, how are arrays returned? Is't not safe to return a char[] from a function if it's allocated on the stack?!? I must have been messed up really good then, because as a GC'ed language*think*assumed one was free to return a string (char[]) from a function. IthatI even already did it, but I may be mistaken (or I was just very luckHmm.... The behavior for static arrays seems fairly innefficient... And what about: classA [1000] array; Then I guess the classes themselves are on the heap, but the array is not? And if the array is returned, then it is copied to the heap. Or does the compiler detects this case and immediately allocate the array on the heap? What's the best way to allocate a fixed-size array directly on the heap? Is this documented anywhere? I read the docs from cover to cover but it seems I missed a few things... I checked again in the sections that seem relevant and didn't find any of this mentionned.the stack didn't get corrupted)...Dynamic arrays (such as char[]) are on the heap, so may be freely returned. I assume that if one returns a static array (such as char[256]) then a copy would be made. Of course, you could define a function as returning a dynamic array, and still return the value of a static array. As I understand it, its data is copied to a new dynamic array, and a referance to the anonymous dynamic array is returned. -- Chris Sauls
May 05 2005
Maxime Larose wrote:"Chris Sauls" <ibisbasenji gmail.com> wrote in message news:d5csgj$sha$1 digitaldaemon.com...Yes. Array just contains references to classes.Maxime Larose wrote:IThen, how are arrays returned? Is't not safe to return a char[] from a function if it's allocated on the stack?!? I must have been messed up really good then, because as a GC'ed language*think*assumed one was free to return a string (char[]) from a function. IthatI even already did it, but I may be mistaken (or I was just very luckHmm.... The behavior for static arrays seems fairly innefficient... And what about: classA [1000] array; Then I guess the classes themselves are on the heap, but the array is not?the stack didn't get corrupted)...Dynamic arrays (such as char[]) are on the heap, so may be freely returned. I assume that if one returns a static array (such as char[256]) then a copy would be made. Of course, you could define a function as returning a dynamic array, and still return the value of a static array. As I understand it, its data is copied to a new dynamic array, and a referance to the anonymous dynamic array is returned. -- Chris SaulsAnd if the array is returned, then it is copied to the heap.Array can't be returned, only reference i.e. dynamic array. So actually reference to stack is return, and your program will crash.Or does the compiler detects this case and immediately allocate the array on the heap?Fixed-size arrays defined inside a function are always on stack.What's the best way to allocate a fixed-size array directly on the heap?int[] array = new int[1000];Is this documented anywhere? I read the docs from cover to cover but it seems I missed a few things... I checked again in the sections that seem relevant and didn't find any of this mentionned.-- Vladimir
May 05 2005
Chris Sauls wrote:Maxime Larose wrote:Function can't return static arrays, only dynamic. Look at the following: int[] test() { int[10] x; x[0] = 10; return x; // Converting int[10] to int[] means getting reference of int, // so this function returns reference to array on the stack // which is error. } int main() { int[] u; u = test(); writefln(u[0]); // prints 10 int[100] g; writefln(u[0]); // prints garbage } May be compiler should produce a warning here.Then, how are arrays returned? Is't not safe to return a char[] from a function if it's allocated on the stack?!? I must have been messed up really good then, because as a GC'ed language I assumed one was free to return a string (char[]) from a function. I *think* I even already did it, but I may be mistaken (or I was just very luck that the stack didn't get corrupted)...Dynamic arrays (such as char[]) are on the heap, so may be freely returned. I assume that if one returns a static array (such as char[256]) then a copy would be made.Of course, you could define a function as returning a dynamic array, and still return the value of a static array. As I understand it, its data is copied to a new dynamic array, and a referance to the anonymous dynamic array is returned. -- Chris Sauls-- Vladimir
May 05 2005
Vladimir wrote:int[] test() { int[10] x; x[0] = 10; return x; // Converting int[10] to int[] means getting reference of int, // so this function returns reference to array on the stack // which is error. } int main() { int[] u; u = test(); writefln(u[0]); // prints 10 int[100] g; writefln(u[0]); // prints garbage } May be compiler should produce a warning here.That's insane. The compiler shouldn't issue a warning. And it shouldn't cause the program to crash. Or to print garbage. The compiler should be able to detect when a function returns a static array. In such cases, it should allocate the array on the heap instead of the stack. --BenjiSmith
May 05 2005
"Benji Smith" <dlanguage xxagg.com> wrote in message news:d5dls4$1jat$2 digitaldaemon.com...Vladimir wrote:The D spec http://www.digitalmars.com/d/function.html section Local Variables says its illegal to return the address of a local variable - which presumably should be expanded to include addresses of local static arrays. None of the errors in the Local Variables section are enforced by dmd.int[] test() { int[10] x; x[0] = 10; return x; // Converting int[10] to int[] means getting reference of int, // so this function returns reference to array on the stack // which is error. } int main() { int[] u; u = test(); writefln(u[0]); // prints 10 int[100] g; writefln(u[0]); // prints garbage } May be compiler should produce a warning here.That's insane. The compiler shouldn't issue a warning. And it shouldn't cause the program to crash. Or to print garbage. The compiler should be able to detect when a function returns a static array. In such cases, it should allocate the array on the heap instead of the stack. --BenjiSmith
May 05 2005
Ben Hinkle wrote:The D spec http://www.digitalmars.com/d/function.html section Local Variables says its illegal to return the address of a local variable - which presumably should be expanded to include addresses of local static arrays. None of the errors in the Local Variables section are enforced by dmd.So this code should produce an error? char[] getMyString() { char[6] myString = "string"; return myString; } I repeat: that's insane. --BenjiSmith
May 05 2005
"Benji Smith" <dlanguage xxagg.com> wrote in message news:d5dnmt$1lfp$1 digitaldaemon.com...Ben Hinkle wrote:yes - the initializer "string" is copied onto the stack space for myString. The "return myString" is independent of the inialization and it would behave exactly the same as if myString had been left in its initial state (filled with 0xFF's).The D spec http://www.digitalmars.com/d/function.html section Local Variables says its illegal to return the address of a local variable - which presumably should be expanded to include addresses of local static arrays. None of the errors in the Local Variables section are enforced by dmd.So this code should produce an error? char[] getMyString() { char[6] myString = "string"; return myString; }I repeat: that's insane.IYHO. It makes complete sense to me. I would be shocked if the compiler automatically allocated space on the heap and started copying data from the stack to the heap in order to avoid returning a stack object. In particular why stop at static arrays? Why not copy any pointer to a local variable to the heap and return that instead?
May 05 2005
Ben Hinkle wrote:IYHO. It makes complete sense to me. I would be shocked if the compiler automatically allocated space on the heap and started copying data from the stack to the heap in order to avoid returning a stack object. In particular why stop at static arrays? Why not copy any pointer to a local variable to the heap and return that instead?I don't think the compiler should *copy* data from the stack to the heap. I think--if I'm returning a variable from a function--the compiler should be smart enough to allocate it on the heap in the first place. And I don't think this is just a problem with static arrays. I think it's problem with any locally allocated variable. If I use the "return" keyword, the variable should be allocated on the heap. --BenjiSmith
May 05 2005
Benji Smith wrote:Ben Hinkle wrote:One problem here is that this will lead to inconsitent behavior of the language, or else great compiler complexity. What happens when somebody passes a pointer to a stack variable to a function, and then returns what the function returns? How is the compiler to know whether the function returns a pointer to the local variable, or something totally unrelated?IYHO. It makes complete sense to me. I would be shocked if the compiler automatically allocated space on the heap and started copying data from the stack to the heap in order to avoid returning a stack object. In particular why stop at static arrays? Why not copy any pointer to a local variable to the heap and return that instead?I don't think the compiler should *copy* data from the stack to the heap. I think--if I'm returning a variable from a function--the compiler should be smart enough to allocate it on the heap in the first place. And I don't think this is just a problem with static arrays. I think it's problem with any locally allocated variable. If I use the "return" keyword, the variable should be allocated on the heap.
May 05 2005
Hmmm..... No wonder I was messed up. All of this is *extremely* error-prone. It should be either: 1) all arrays are allocated on the heap; or 2) compiler detects return of static array and issues an _error_ (and not a warning); or 3) allocation of static array to dynamic automatically copies to the heap (this is an inferior solution IMO because hidden things are happening under the hood) It suits my purposes just fine in this case (I want speed over (almost) anything else), but honestly, as Benji puts it, it is insane... Max "Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d5dmil$1kaa$1 digitaldaemon.com..."Benji Smith" <dlanguage xxagg.com> wrote in message news:d5dls4$1jat$2 digitaldaemon.com...referenceVladimir wrote:int[] test() { int[10] x; x[0] = 10; return x; // Converting int[10] to int[] means gettingtheof int, // so this function returns reference to array onprogramstack // which is error. } int main() { int[] u; u = test(); writefln(u[0]); // prints 10 int[100] g; writefln(u[0]); // prints garbage } May be compiler should produce a warning here.That's insane. The compiler shouldn't issue a warning. And it shouldn't cause theofto crash. Or to print garbage. The compiler should be able to detect when a function returns a static array. In such cases, it should allocate the array on the heap insteadwhichthe stack. --BenjiSmithThe D spec http://www.digitalmars.com/d/function.html section Local Variables says its illegal to return the address of a local variable -presumably should be expanded to include addresses of local static arrays. None of the errors in the Local Variables section are enforced by dmd.
May 05 2005
In article <d5do0j$1lvt$1 digitaldaemon.com>, Maxime Larose says...Hmmm..... No wonder I was messed up. All of this is *extremely* error-prone. It should be either: 1) all arrays are allocated on the heap; orNot desirable.2) compiler detects return of static array and issues an _error_ (and not a warning); orThis would be nice, but the C++ compilers I've used don't typically error here so I don't expect D to either. Perhaps it could at least try to warn though? (I wouldn't expect 100% accuracy)3) allocation of static array to dynamic automatically copies to the heap (this is an inferior solution IMO because hidden things are happening under the hood)Not desirable. Say I did this: void f(int[] x) {} void main() { int[100] a; f(a); } By your argument, a should be copied when f is called, while I clearly want it to be passed by reference. There's an easy fix for the sample code though: int[] test(){ int[10] x; x[0]=10; return x.dup; } This should create a dynamic copy of the static array. Sean
May 05 2005
(The problem here is solely with arrays. All other return values (ints, bits, long, etc.) will be returned via a register - well, perhaps there is a problem with 64-bits and 128-bits types afterall... On 32 bits machines at least). Anyway, the bottom line is that it is very easy to loose track of how the array was constructed. There is no difference in syntax that would make it easy to spot that a particular array was allocated on the stack and another one not. void someMethod(char [] string); main { char [1000] array1; .... I'm doing stuff... ... for a long time, say 60+ lines... someMethod(array1); // will crash } The above call will crash, even if syntaxically everything is 100% kosher (the call respect the caller's signature to the letter). Now, that's error prone... (and don't tell me that methods shouldn't be 60 lines long, that's not the point) Your analogy to C++ doesn't really hold, because C++ isn't GC'ed. Yes, C++ will cut corners and take away convenience because its a stone age language. In C++, you save 0.00005% of CPU time (which costs nothing) rather than saving: (the 3 seconds it takes _every time_ for the developper to check how the array was constructed * how many times he has to check during the lifetime of the system) + the hours it takes to debug the occasional core dump + all the indirect costs if the core dump happened at a customer's site and/or on a critical system. A new language should eliminate such problems completely - or at least by default. There is _absolutely_ no good reasons why arrays shouldn't be created on the heap in D. However, easily allowing one to create arrays on the stack shouldn't be prohibited. Deviating from the default, it would then become the responsibility of the programmer to know what he is doing. Doing it the other way around is backwards. So, at the _very_ least, it should be a compiler error. No matter how C++ does it. Max BTW, a very interesting essay was written by Paul Graham about languages of the future. The "hundred year language" if I remember correctly. Maybe you'd like to check it out. It discusses convenience (for programmers) vs raw speed. I don't fully agree with him in that I think there are still more applications needing raw speed than he seems to think, but I believe he is right about the overall tangent things will take. "Sean Kelly" <sean f4.ca> wrote in message news:d5dqh7$1ntc$1 digitaldaemon.com...In article <d5do0j$1lvt$1 digitaldaemon.com>, Maxime Larose says...error-prone.Hmmm..... No wonder I was messed up. All of this is *extremely*aIt should be either: 1) all arrays are allocated on the heap; orNot desirable.2) compiler detects return of static array and issues an _error_ (and notherewarning); orThis would be nice, but the C++ compilers I've used don't typically errorso I don't expect D to either. Perhaps it could at least try to warnthough? (Iwouldn't expect 100% accuracy)under3) allocation of static array to dynamic automatically copies to the heap (this is an inferior solution IMO because hidden things are happeningwant itthe hood)Not desirable. Say I did this: void f(int[] x) {} void main() { int[100] a; f(a); } By your argument, a should be copied when f is called, while I clearlyto be passed by reference. There's an easy fix for the sample code though: int[] test(){ int[10] x; x[0]=10; return x.dup; } This should create a dynamic copy of the static array. Sean
May 05 2005
Sean Kelly wrote:In article <d5do0j$1lvt$1 digitaldaemon.com>, Maxime Larose says...Sean, would you mind elaborating on this a little bit? To me, it seems much more reasonable to allocate arrays on the heap (as the default behavior) and to only allocate them on the stack when specifically requested by the programmer through some sort of obviously-different syntax. If the "not desirable" response is primarily just because of a change in semantics from c/c++, then I don't think that's a reasonable argument. But if there's some other reason why heap-allocation wouldn't be a desirable default for arrays, please let me know. --Benji1) all arrays are allocated on the heap; orNot desirable.
May 05 2005
Benji Smith wrote:Sean Kelly wrote:I think the thing that both you and Maxime are missing is the concept of dynamic arrays. You can think of a dynamic array variable as like this template struct: struct DynArray(T) { T *array; uint length; } Fixed length arrays, on the other hand, are just like C arrays. If you think about things this way, then it is very obvious why things work the way they do. char[10] a1; // the 10 bytes are literally on the stack char[] a2; // think of this like: DynArray!(char) a2; With dynamic arrays, the dynamic array *variable* is stored on the stack. But all that that variable contains is pointer and length data. The pointer doesn't point to anything until you initialize it. Then the stuff that it points to is on the heap. The rule is consistent: local function variables are stored on the stack. The difference between fixed-length and dynamic arrays is what constitutes the variable.In article <d5do0j$1lvt$1 digitaldaemon.com>, Maxime Larose says...Sean, would you mind elaborating on this a little bit? To me, it seems much more reasonable to allocate arrays on the heap (as the default behavior) and to only allocate them on the stack when specifically requested by the programmer through some sort of obviously-different syntax.1) all arrays are allocated on the heap; orNot desirable.
May 05 2005
[snip]With dynamic arrays, the dynamic array *variable* is stored on the stack. But all that that variable contains is pointer and length data. The pointer doesn't point to anything until you initialize it. Then the stuff that it points to is on the heap.umm - a dyanmic array can point to the stack. That's what happens with char[10] x; char[] y = x; There is no heap allocation going on there. If you try to resize y by doing something like y.length = 20; then since the stack space doesn't have the capacity a new pointer to 20 chars will be allocated from the heap and y's pointer will then indeed point to the heap.The rule is consistent: local function variables are stored on the stack. The difference between fixed-length and dynamic arrays is what constitutes the variable.
May 05 2005
Ben Hinkle wrote:[snip]True, of course. I was being overliy simplistic :/With dynamic arrays, the dynamic array *variable* is stored on the stack. But all that that variable contains is pointer and length data. The pointer doesn't point to anything until you initialize it. Then the stuff that it points to is on the heap.umm - a dyanmic array can point to the stack. That's what happens with
May 05 2005
In article <d5dtim$1qhn$1 digitaldaemon.com>, Benji Smith says...Sean Kelly wrote:Perhaps it's because I'm so accustomed to C++, but I don't see any reason to pay for a heap allocation if I don't need to. If I'm using a fixed-size array that doesn't need to be passed out of scope then why not put it on the stack? To me, the syntax clearly differentiates between the two declaration types so I see little risk of a mistake. Here are both versions for comparison: int[1000] a; // 1000 int array on the stack int[] b = new int[1000]; // 1000 int array on the heap int[] c; c.length = 1000; // also a 1000 int array on the heap Returning a reference to stack data is a mistake I've personally never made (probably because I've had it drummed into me since day 1 that this is a Bad Thing), so I can't comment on the potential increase in safety that defaulting to heap allocations would provide. I'll grant that heap allocations in a good GC language can be exceedingly fast, but then that's just more stuff to clean up later on. SeanIn article <d5do0j$1lvt$1 digitaldaemon.com>, Maxime Larose says...Sean, would you mind elaborating on this a little bit? To me, it seems much more reasonable to allocate arrays on the heap (as the default behavior) and to only allocate them on the stack when specifically requested by the programmer through some sort of obviously-different syntax. If the "not desirable" response is primarily just because of a change in semantics from c/c++, then I don't think that's a reasonable argument. But if there's some other reason why heap-allocation wouldn't be a desirable default for arrays, please let me know.1) all arrays are allocated on the heap; orNot desirable.
May 05 2005
Chris Sauls wrote:Dynamic arrays (such as char[]) are on the heap, so may be freely returned. I assume that if one returns a static array (such as char[256]) then a copy would be made. Of course, you could define a function as returning a dynamic array, and still return the value of a static array. As I understand it, its data is copied to a new dynamic array, and a referance to the anonymous dynamic array is returned.This is not correct. If you assign a static array to a dynamic array variable, then you get a dynamic array which points to the same memory as the static array. However, you can dup the array: char[1000] static_array; return static_array.dup; 'dup' copies the array to a new location. This, of course, must be on the heap.
May 05 2005