It was recommended to post this message on the clang list rather than the llvm list where it originally appeared…
Is there interest in enhancing the objc++ compiler to make objc mechanisms friendly to the newer features of c++? For instance…
- making blocks movable so that they can capture things like unique_ptr<> and still be moved off the stack
This should be relatively simple. Although the interface is a copy, it is effectively a move operation (it either increments a reference count or modifies the source to use forwarding pointers). I don’t see why blocks in C++11 or later shouldn’t always use move constructors for __block-qualified variables where available.
We already use the move constructor when moving the contents of __block variables to the heap.
I believe James is referring to a non-__block capture of move-only type. For that, we run into two very similar problems:
- We have no way of guaranteeing that a stack block will be abandoned after it is copied to the heap; there is no forwarding mechanism for block objects.
- We have no way of guaranteeing that the original variable will be abandoned after it is captured in the block; there is no “capture-by-move” for block captures.
I don’t know how to solve either of these problems without major extensions to the current language design of blocks. Fortunately, __block captures exist; they’re not perfectly efficient, but they exist.
- making @property declarations work with move-only types like unique_ptr<>
This shouldn’t be too hard: the compiler already synthesises property setters and getters, though it’s not quite clear what these would look like. I believe that currently all C++ properties are exposed via copies and take a reference in the set method. Would you want this to implicitly take an r-value reference for anything that’s only move constructable, or would you add an extra ‘move’ attribute to the property to enforce the fact that it takes an r-value reference?
I think we actually take the parameter as a pr-value, which in some ways is better because it means that you can pass something either by copy or by move. I don’t know if we then try to move-assign the ivar from the parameter, but we certainly should.
I think the more interesting question is the type of the getter. The getter really can’t return a && or pr-value. Do we recognize that a type is move-only and just make the getter return a
const &? Does that mean we forbid synthesizing such a property as atomic?
There’s the related issue that NSInvocation is dangerously broken with move-only types (and anything that has a nontrivial copy constructor), because there’s no way of forcing the objects to be correctly copied. It would be nice if each selector came with a move helper for its arg frame, but doing that in a way that doesn’t massively bloat the binary size is nontrivial.
- enabling std::weak_ptr<> to weakly store an objc pointer under ARC. (see radar: 31177975)
I’m not sure what this would look like. Currently, you create std::weak_ptr from std::shared_ptr. Presumably you’d want to specialise std::shared_ptr for id and have it just be a bare pointer that called the ARC functions on copy / move, then implement the corresponding std::weak_ptr specialisation do the same thing with a __weak id.
I seem to recall that we also need some type traits for ObjC objects so that you can implement a specialisation for any ObjC object type, but not for non-object types.
- add a mechanism to allow template metaprogramming to make full use of selectors. (see radar: 30812297)
This would be a nice feature, but it’s not clear what it would look like in the language. You can make a selector a template parameter already, but what would the application look like?
And what would the rules be for type-checking such an application? If we’re talking about C++ interactions here, we can’t very well pretend that the parameters and return value are all going to be
id. (I wouldn’t want to add new dependencies on that behavior anyway, even in pure Objective-C.)
Also, you can’t actually make a selector a template argument today. You can use SEL as the type of a template parameter, but it’s basically useless because @selector is not a constant expression.
Now, there’s an idea we’ve been kicking around for a long time to support typed selectors; I guess they would look something like
for the type of
Note that that argument is just a function type, and that it’s not the actual type of an IMP because both
_cmd are implicit. That’s an interesting thing to discuss. You could make an argument that
self should be explicit, so that you could say “this is a selector that only works on object arguments of a certain type”. That would be more type-safe, but I would worry about it making it more awkward to use this for the sorts of dynamic features that people use untyped selectors for today. Maybe it’d be fine as long as you could convert
Anyway, since it’s an ordinary function type, it can carry attributes like NS_RETURNS_RETAINED and NS_CONSUMED because we already taught the type system about those for ARC. (It can’t express the behavior of -init methods unless
self is an explicit parameter, though.)
I think the application syntax is pretty obvious: you would just call the selector as if it were a C function, with the first argument being the receiver, and the compiler would automatically call the right objc_msgSend variant for the type.
You’d need some way of constructing one of these, probably by referring to an existing method. Maybe that could be @selector(-Foo.bar) or something.
Anyway, if you had that, you could then add special template support for them.