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

David Blaikie dblaikie at gmail.com
Fri Oct 3 14:50:05 PDT 2014


On Fri, Oct 3, 2014 at 12:55 PM, Jared Grubb <jared.grubb at gmail.com> wrote:

> I spoke with Marshall briefly about this at CppCon. My suggestion is that
> std::function should either:
>  * correctly capture blocks and just work (as this patch does)
>  * compile with error if you try it (and also maybe add a convenience
> adaptor like you suggest to allow it to manually work)
>
> 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.
>

What runtime issues are you referring to? Could you provide a simple
standalone complete example?

I assume the issue is that std::function will capture the block's
(presumably raw) pointer by value but do none of the increment/decrement.
This doesn't seem necessarily broken & I'm not sure (for myself) it merits
library support to protect.

This would be the same behavior as any other lifetime issues with pointer
captures.

  std::function<...> func() {
    int i;
    int *j = &i;
    return [=j] () { ... }; // captured j by value, but it points to
something that goes out of scope at the end of the function. Bad.
  }

But similar code isn't a problem at all:

  void func(std::function<...>); // func calls the std::function, maybe
copies it around, but doesn't copy it to global storage/anywhere that
outlives the
  ...
  int i;
  int *j = &i;
  func([=j]() { ... });


>
> Marshall suggested to me that we just make it work, so that's the approach
> I've taken here. I agree it is a bit "un-pure" to add something like this
> into libcxx, but given that clang handles blocks natively (with -fblocks),
> maybe that's ok.
>
> 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.
>
> Jared
>
> On Oct 1, 2014, at 14:57, David Blaikie <dblaikie at gmail.com> wrote:
>
> [+Marshall as libc++ maintainer]
>
> What would it look like if we just provided a value-semantic-C++ wrapper
> around blocks, translating C++ move/copy operations down to the
> Block_copy/release/etc operations?
>
> That way it'd be orthogonal to the type erasure of std::function and could
> be used just for a convenience when using blocks in C++ code anyway:
>
>   auto x = make_cpp_block(/* block stuff */);
>   auto y = x;
>   x();
>   etc...
>
> (& then you'd compose them with "std::function<...> f =
> make_cpp_block(...);" (the block wrapper could have an implicit conversion
> to std::function))
>
> It's a little more text, but doesn't require an extension to the standard
> library, and can be used independently.
>
> On Wed, Oct 1, 2014 at 11:38 AM, Jared Grubb <jared.grubb at gmail.com>
> wrote:
>
>> == Background:
>> std::function will wrap anything that is callable (and can be
>> copied/moved). Blocks are copyable and callable, however you need to use
>> the reference counting Block_copy/Block_release functions.
>>
>> == Request for Comment on the Patch:
>> I am working on a patch that will allow std::function to capture blocks
>> correctly (under the right feature guards).
>>
>> Functionally, the patch is complete. However, it's not checkin-ready as I
>> had a couple questions on the approach:
>>  * Is the approach right? I specialized the __func storage class, as that
>> seems to be the right thing to customize.
>>  * I have included some unit test implementations. There are quite a few
>> std::function unit tests, so I wanted to make sure I was on the right track
>> before I do all of them.
>>  * Should I add tests for ObjC++ code, under ARC and non-ARC scenarios?
>> There are no ObjC++ files in libcxx, and the test-runner does not yet
>> support them. Adding this is not hard, but it's a change in how things are
>> today.
>>
>> If this looks like it's on the right track, I will flush out the rest of
>> the unit tests, and optionally add ObjC++ unit tests.
>>
>>
>>
>>
>> Jared
>>
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141003/8f564cdb/attachment.html>


More information about the cfe-dev mailing list