[cfe-dev] libcxx: std::function should be able to capture blocks

Jared Grubb jared.grubb at gmail.com
Thu Oct 9 00:03:39 PDT 2014


Sorry for the delay. I was traveling abroad this weekend.

> On Oct 3, 2014, at 14:13, Eric Fiselier <eric at efcs.ca <mailto:eric at efcs.ca>> wrote:

> 
> I'm quite unfamiliar with Apple Blocks and their lifetime semantics. Would you be able to point to some documentation? 

The official ref is a bit dense to read but here it is:
 * http://clang.llvm.org/docs/Block-ABI-Apple.html <http://clang.llvm.org/docs/Block-ABI-Apple.html>

The short of it is that blocks, like lambdas, are structs. The block-pointer ("R (^)(Args)") is a pointer to that struct. The block-pointer is callable, but there is no syntax to "dereference" the block-pointer, so you cant directly copy/move a block. 

To extend the life of a block (eg, put it in a std::function), you must call Block_copy, save the (probably different) pointer that is returned, and eventually balance out with a call to Block_release on that returned pointer.

The hand-wavey description of what is happening is this:
 * If you call Block_copy on a stack-based block, it returns a (different) pointer to a heap-based block (with ref-count 1).
 * If you call Block_copy on a heap-based block, it returns the same pointer (and you have a new ref to it).

The ABI has the detailed nuances (eg, static-scoped blocks, blocks with trivial capture, blocks in ObjC), but the simple "Block_copy + keep + Block_release" sequence is how you extend a block's life in C and C++.

> > The current problem is that if you write something like this:
>    template <typename F> doSomething(F&& functor) { std::function<...> capturing = std::forward<F>(functor); ... }
> This works great for lambdas. For blocks, it compiles just fine but has runtime issues.
> 
> I think in understand this, but would you be able to flush out your example?

Yes, let me do that in my next email since David also asked this.

> 
> > But, after looking over this patch if it doesnt feel right, I would at least suggest we add =delete/enable_if's to the right places so at least incorrect code wont compile
> 
> This patch feels right. I would be happy to review it once it is a complete. Also, is it possible to test Apple Blocks on Linux?

I dont know this personally, but as long as it has Block.h (part of compiler-rt) and clang is compiled with block support, it should work. But, I havent tried it personally.

Jared

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141009/76b20c6a/attachment.html>


More information about the cfe-dev mailing list