[cfe-dev] blocks and lambdas
James Gregurich
bayoubengal at mac.com
Thu Feb 10 11:54:18 PST 2011
On Feb 10, 2011, at 6:56 AM, Bruno Santos wrote:
>>
>> Why is the following structure incapable of describing a C++ lambda
>> function?
>>
>>
>> struct Block_basic {
>> void *isa;
>> int Block_flags; /* int32_t */
>> int Block_size; /* XXX should be packed into Block_flags */
>> void (*Block_invoke)(void *);
>> void (*Block_copy)(void *dst, void *src); /* iff
>> BLOCK_HAS_COPY_DISPOSE */
>> void (*Block_dispose)(void *); /* iff
>> BLOCK_HAS_COPY_DISPOSE */
>> /* long params[0]; // where const imports, __block storage
>> references, etc. get laid down */
>> };
>>
>
> It can't, a lambda can be used as a function pointer!
>
> Lambdas are syntactic sugar for function objects, which is fundamentally
> different from what blocks are. What you are asking is lot of baggage
> for nothing, from a pure C++ perspective, just to be compatible with
> blocks.
A function object is a class with a set of data members and a callback function called 'operator()()'.
A 'block' is a callback function and a set of captured data items.
How is that different?
consider....
#ifdef __BLOCKS__
void
dispatch_sync(dispatch_queue_t dq, void (^work)(void))
{
struct Block_basic *bb = (void *)work;
dispatch_sync_f(dq, work, (dispatch_function_t)bb->Block_invoke);
}
#endif
DISPATCH_NOINLINE
void
dispatch_sync_f(dispatch_queue_t dq, void *ctxt, dispatch_function_t func)
{
...
func(ctxt);
What do I see in this code and Block_basic? I see a callback function (func = Block_invoke), a 'this' pointer (ctxt is a Block_basic instance), a destructor (Block_dispose), and a cloning operation (Block_copy). I even see a 'isa' pointer (analogous to vtable pointer). What is does a single-inheritance C++ class have that this mechanism doesn't have?
If all you do is set the system up so that if a lambda-to-block conversion is requested, the Block_basic structure is set up and mapped to the lambda, that would be enough. If you did that, then lambdas could be passed to libdispatch and the various cocoa/foundation functions that accept blocks as arguments. The developer writes his lambda and passes it to the apple function that accepts blocks....oblivious to the fact that a conversion has taken place. In the case where the lambda is entirely known at compile time and it is known that is is only converted to a block, then you can optimize the situation by just making it into a block at compile time.
I really don't understand what the objection to the concept is. The technical objections I've seen don't seem substantial to me when I look at the details. Do you think easy interoperability between standard technologies and platform-specific technologies is not a desirable goal?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110210/fbe40e44/attachment.html>
More information about the cfe-dev
mailing list