C++ Logo


Advanced search

[std-proposals] Custom call convention per type

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Thu, 28 Jul 2022 23:26:41 +0200
Currently there are multiple problems linked to lifetime of function parameters.
Simply current default behavior does not fit all corner cases.

Example is `std::unique` that generates subpar code because the call
site is a firewall that
prevents the compiler to see at once destructor and move operation.

Now what if we op-in to allow a given type to have lifetime handled differently?

Image we add new contextual keyword like:
class Type arg_destructor_in_callee
Now when the function `void foo(Type arg)` is called, the object `arg`
will be destroyed
in the body of `foo` not by the caller. This will make for compiler
easy to see if object was
moved before the destructor call and then if the destructor was inlined
then it could remove it all. This will work great with `bitcopies` or
`Trivially Relocatable` types.

This will of course affect ABI (this is why keyword not attribute) and
change order of destructor calls.
This could be new reference type (`&&&`??) but this probably will be
big burden on all generic
code as we will need another case to handle this.

Another interesting side effect is that even if this feature need
op-in you can always wrap arbitrary object into type with this did
this and benefice from this, like:

template<typename T>
struct Wrapper arg_destructor_in_callee
    Wrapper (T&& t) : data{ std::move(t) } //implicit constructor
    T data;
template<typename T>
void foo(Wrapper<T> arg)

int main()
And no destructor will be directly called by `main`.

And this brings me to the opposite problem, that in some cases I do
not want to temporarily be destroyed by callee. Then we could define
another keyword `arg_destructor_in_caller` that would force all ABI to
pass this temporary as a hidden pointer.

Would this approach be useful?

Received on 2022-07-28 21:26:53