[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