DMD 0.170 release

Bill Baxter dnewsgroup at billbaxter.com
Tue Oct 17 22:38:38 PDT 2006


Tom S wrote:
> Bill Baxter wrote:
>> In C++ I would just make it a reference parameter, and take the address:
>>
>> void print_addr( IntArrayType& arg )
>> {
>>     writefln(&arg);
>> }
>> void main()
>> {
>>     int[] arr = [1,2,3,4,5];
>>     writefln(&arr);
>>     print_addr(arr);
>> }
>>
>> Then aside from the fact that D is not C++, it would print the same 
>> value for both, and it wouldn't be accessing a static variable.  And 
>> it would be perfectly thread safe.
> 
> 
> Heh, that's not the same case. You can do that it D, except that you'd 
> use inout for the reference. The problem arises when you try to return a 
> delegate literal from a function, it then references stack data which is 
> invalid after the function returns. Speaking of C++ analogies, it is 
> just like returning pointers to stack data. 

I see.  I was mislead into thinking that closures worked because this 
code compiled without complaint and worked fine in release mode:

int delegate(int) AddN(int N)
{
     int _addN(int x) {
         return x + N;
     }
     return &_addN;
}
writefln(AddN(3)(4));


But after recompiling with -g it gives me a garbage answer.  I thought I 
could continue to access the _value_ of the N


BUT! making a local copy of N in the function, it seems to work:

| int delegate(int) AddN(int N)
| {
|     int _addN(int x) {
|         int MyN = N;
|         return x + MyN;
|     }
|     return &_addN;
| }
| writefln(AddN(3)(4));

(prints 7 in debug mode too)


And applying the same idea, this works too:


int delegate(int delegate(inout typeof(AggregateT[0])))
reversed(AggregateT)(inout AggregateT array)
{
     alias typeof(AggregateT[0]) ElemT;
     int _innerFunc(int delegate(inout ElemT) loopBody)
     {
         AggregateT myArr = array;  // make a local ref!
         for (int i = myArr.length-1; i >=0; i--)
         {
             if (loopBody(myArr[i]))
                 break;
         }
         return -99;
     }
     return &_innerFunc;
}

int[] aint = [1,2,3,4,5,6,7];
foreach(int i; reversed(aint)) { ... }

So is that not guaranteed to work?
If it is ok then we have a way to do reversed(foo) without dummy 
classes!  (I'll put aside the issue of "hackish stuff" for the moment.)

Syntactically and functionally it's not much different, but compared 
with the struct version it doesn't leak implementation issues to the 
outside world like having a reverse__ struct dangling out there does.

So now, how to make it look less hackish...

--bb



More information about the Digitalmars-d-announce mailing list