C++ Logo


Advanced search

Re: [std-proposals] Custom call convention per type

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Mon, 8 Aug 2022 11:59:41 +0100
On Thu, Jul 28, 2022 at 10:26 PM Marcin Jaczewski wrote:
> 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.

The following program can be toggled to "destroy in caller" or
"destroy in callee" by setting the global boolean "destroy_in_callee"
to true or false.

I realise that the following code won't give you the optimisation
you're looking for, but is it at least the behaviour you're going for?

// Step 1: Have a global boolean to specify destroy by caller/callee
bool constexpr destroy_in_callee = true;

#include <iostream>

// Step 2 : Write a sample dummy class that says hello and goodbye
struct MyClass {

    bool is_valid = true;

    MyClass(char const* = nullptr)
        std::cout << "Constructing object" << std::endl;

    MyClass(MyClass &&temp)
        temp.is_valid = false;

        if ( false == is_valid ) return;

        std::cout << "Destroying object" << std::endl;

// Step 3: Write a template function to get an L-value reference to a
// temporary object
template <class T>
T &LvalueRef(T &&arg)
    return arg;

#include <optional>

// Step 4: Write a preprocessor macro to create a temporary
// object of type 'optional' from a temporary.
#define ARG(temp) LvalueRef(std::optional<decltype(temp)>( \
                              std::move(temp) ))

// Step 5: Write a function that can either do "destroy by caller"
// or "destroy by callee"
void SomeFunction(std::optional<MyClass> &arg)
    // I have the choice now whether the string
    // gets destroyed in this function or in
    // the calling function.

    if constexpr ( destroy_in_callee ) arg.reset();

int main(void)
// Step 6: Call the function and check where the temporary is destroyed

    SomeFunction( ARG(MyClass(nullptr)) ),
        (std::cout << "Hello again from Main" << std::endl);

    std::cout << "Last line in body of Main" << std::endl;

This program will print either:

Constructing object
Hello again from Main
Destroying object
Last line in body of Main


Constructing object
Destroying object
Hello again from Main
Last line in body of Main

Received on 2022-08-08 10:59:54