May 05, 2005
"Benji Smith" <dlanguage@xxagg.com> wrote in message news:d5dnmt$1lfp$1@digitaldaemon.com...
> 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;
> }

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).

> 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
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; or

Not desirable.

>2) compiler detects return of static array and issues an _error_ (and not a
>warning); or

This 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
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
(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...
> >
> >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
>
> Not desirable.
>
> >2) compiler detects return of static array and issues an _error_ (and not
a
> >warning); or
>
> This 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
Sean Kelly wrote:
> In article <d5do0j$1lvt$1@digitaldaemon.com>, Maxime Larose says...
>>1) all arrays are allocated on the heap; or
> 
> Not desirable.

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.

--Benji
May 05, 2005
Benji Smith wrote:
> 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.

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?
May 05, 2005
Benji Smith wrote:
> Sean Kelly wrote:
> 
>> In article <d5do0j$1lvt$1@digitaldaemon.com>, Maxime Larose says...
>>
>>> 1) all arrays are allocated on the heap; or
>>
>> Not desirable.
> 
> 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.

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.
May 05, 2005
In article <d5dtim$1qhn$1@digitaldaemon.com>, Benji Smith says...
>
>Sean Kelly wrote:
>> In article <d5do0j$1lvt$1@digitaldaemon.com>, Maxime Larose says...
>>>1) all arrays are allocated on the heap; or
>> 
>> Not desirable.
>
>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.

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.


Sean


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]
> 
>>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

True, of course.  I was being overliy simplistic :/
1 2 3 4
Next ›   Last »