[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