[cfe-dev] blocks and lambdas

Bruno Santos bsantos at av.it.pt
Thu Feb 10 12:35:01 PST 2011


Qui, 2011-02-10 às 11:54 -0800, James Gregurich escreveu:
> 
> 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? 
> 
> 

The problem is the "set of captured items". If a lambda does not capture
any items it can be used as a function pointer, I don't think you can do
that with a block since it carries baggage with it even if you don't
capture items. It would also violate one of the fundamental design
philosophies behind C++: "you don't pay for what you don't use".



> 
> 
> 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 --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5428 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110210/a9a935f5/attachment.bin>


More information about the cfe-dev mailing list