[cfe-dev] objc++ enhancements for new c++ features

John McCall via cfe-dev cfe-dev at lists.llvm.org
Thu Mar 29 12:01:29 PDT 2018


> On Mar 29, 2018, at 2:47 PM, John McCall via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> 
>> On Mar 29, 2018, at 2:31 PM, David Chisnall <David.Chisnall at cl.cam.ac.uk> wrote:
>> On 29 Mar 2018, at 19:22, John McCall <rjmccall at apple.com> wrote:
>>> 
>>>> On a related note, I’ve been considering whether it’s possible to provide helpers to improve NSInvocation’s handling of Objective-C++ messages that take types with either nontrivial copy constructors or no copy constructor.
>>>> 
>>>> My motivation for this was writing some code using higher-order messaging to perform things in another thread, which worked fine until I passed it a std::shared_ptr, at which point NSInvocation did a simple memcpy of the argument frame and I was left with a dangling pointer.  I eventually rewrote this code to use lambdas, but it would be nice if an NSInvocation constructed from a message containing a std::shared_ptr argument actually did the reference count manipulations correctly when copying the argument from the stack / registers into the NSInvocation object.  Most methods have trivially copyable arguments / return values (except for Objective-C objects, which NSInvocation can already handle automatically), so the metadata would only have to be for the (hopefully, relatively small) subset of C++ types that are not trivially copyable and are passed as Objective-C method arguments.  Do you have any thoughts?
>>> 
>>> Honestly?  I think NSInvocation ought to be deprecated in favor of just using blocks or, if blocks are unacceptable, static code-generation techniques.  NSInvocation works well enough for a highly reduced set of function prototypes, but the idea that it's going to transparently support every possible thing that the compiler knows how to do in a call seems pretty fanciful to me.
>> 
>> Unfortunately, using blocks means that you can’t use any of the higher-order messaging patterns, which makes the code a lot more verbose and a lot less composable.  If C++ compile-time reflection lands then I suppose most use cases could be handled with that, as long as we provide ObjC++ extensions to allow the reflection to work in the same way.
> 
> Well, but does that mean that blocks aren't the right answer, or does it mean that you should be generating your blocks with code-generation techniques like macros or templates?

For example, to combine a couple streams here:

If you could write @selector(-NSWidget.foo:bar:), and that you gave you a SEL<void(NSWidget*, float, std::unique_ptr<Gadget> &&)>, it would be relatively straightforward to write a variadic template function that took that selector and the corresponding arguments and a dispatch queue and called dispatch_after with a block which captured all the arguments by-value and in its body did a message of that selector which forwarded all the captured arguments.

John.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180329/4c6bc339/attachment.html>


More information about the cfe-dev mailing list