-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
P2785 Relocating prvalues and potential ABI impacts #187
Comments
I have a few concerns, not having yet read your paper.
|
Thank you for your response.
I don't know what "has" mean here (declared? only publicly? implicitly? eligible?), but I'm open to align the constraints on the move constructor to something that fit the spirit of existing rules.
|
Last year P2785R3 was presented and did not reach consensus. The proposal has been reworked to a forth revision, visible here (not yet the official bump). As the main author of the paper, I'd like to discuss with you the potential ABI breaks this proposal might introduce.
P2785 introduces the relocation operation, by the means of a new relocation constructor
T(T)
, which simultaneously constructs a new instance and destroys its source instance. To avoid introducing a new value category, we propose relocation to happen from prvalues. And to allow the relocation of automatic variables, we introduce the newreloc
operator which simply changes the value category from lvalue to prvalue. Once the variable has changed its value category, a constructor is selected from the relocation, the move or the copy constructor. Relocation will only effectively happen if the relocation constructor is selected. Once a variable has been passed toreloc
, it can no longer be used in the rest of its scope, regardless of which constructor was selected.So far so good, ABI problems start to happen in the following scenario:
Since
x
is the function parameter, on Itaniumfoo
has no control over its lifetime, and hence calling the relocation constructor ofx
in that scenario will double the object destruction (once in the relocation constructor call, once when control returns to foo's caller).We are well aware of that issue and are doing our best not to impose an ABI break. We came up with the following rule: When selecting a constructor, if the source object is a function parameter passed by value, and its type provides an eligible move constructor, then the relocation constructor (if any) may be discarded during overload resolution. Whether the relocation constructor is discarded is implementation-defined. The destruction of the source object, should the relocation constructor not be selected, is postponed until control returns at the caller site.
The corollary to this rule, is that functions that takes parameters by value, whose type declares a relocation constructor but no move constructor, must have control over the ownership of such parameters. Such functions may have a different mangling to better detect breakages.
With this rule, ABI breaks are opt-in. They will only happen when someone defines a relocation constructor in their class and defines no move constructor. P2785 does not discuss in details how the STL shall evolve to support relocation (it will be done in another proposal once P2785 is mature enough), but one thing is certain: a relocation constructor will be declared in classes where there is already a move constructor. This addition will cause no ABI breaks because of the rule above.
Now there may be the case of types that become relocate-only by accident. Let's consider a putative
gsl::non_null
with a relocation constructor. Thengsl::non_null<std::unique_ptr<int>>
will only be relocatable because of its template parameter. We believe that such breakages can still be anticipated and controlled (advertise the change, use a new non_null wrapper type, etc...)What do you think of this proposal in terms of ABI? Do you have any concerns in terms of ABI? Do you think the suggested rule is enough? Feel free to ask for clarifications. Thank you for your time.
The text was updated successfully, but these errors were encountered: