On the richness of C++

Jason House jason.james.house at gmail.com
Tue Apr 15 19:13:42 PDT 2008


Walter Bright wrote: 
>>>> Closures capture variables by reference.  This means that creating
>>>> delegates inside a foreach loop (with deferred evaluation) could fail
>>>> to have the expected behavior.  Bind stores stuff by value, so I
>>>> still find myself using bind libraries.
>>> If you expect captured variables to be by value, sure. But I always
>>> expected them to be by reference!
>> 
>> By reference is nice in many cases, but in others it's frustrating.  How
>> do you implement the following?
>> 
>> foreach(job; queue)
>>   runthread(void delegate(){job.execute;});
>> 
>> (Somehow I expect someone to pick apart the example, but I hope the point
>> is clear)
> 
> No, the point isn't clear. Closures can handle multiple threads
> accessing it.

I probably should not have rushed to make an example before running out the
door.  But I'll still run with the example...

For each delegate, the job variable gets captured.  Each delegate will have
access to the job variable.  In cases of defered delegate execution,
changes to the job variable will affect what the delegate does.

In my example, what happens if runthread is really access to a non-blocking
thread pool that queues excess commands.  When the thread pool gets around
to running the delegate passed in, what will be in "job"?  If this is done
after the loop finishes, the value inside job will be the final value from
opApply (or worse, corrupt).

The net effect is that a queue of 50 jobs may have the final job executed 50
times, and the first 49 jobs are never run.  This does not seem like
correct behavior to me.



More information about the Digitalmars-d mailing list