[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