C++ Logo

std-proposals

Advanced search

Re: [std-proposals] New intrinsic type -- prvalue

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Mon, 20 Oct 2025 07:41:30 +0000
On Monday, October 20, 2025, Andre Kostur wrote:

> Your example doesn’t follow your premise. You suggested that you could do
> this by only declaring this ‘prvalue’ type, yet you had to modify Func in
> order to use it.
>



'Func' doesn't need to be modified. When I wrote the following:

    template<typename T>
    void Func(T &&arg)
    {
        T var( arg() );
    }

I was showing how the compiler would implement it under the hood.
Specifically, on x86_64 Linux, rather than the RDI register containing the
address of an object of type T, it would instead contain the address of a
function that returns a T by value.

Also in my previous post, I showed a compiler-generated function:

    string CompilerGenerated000(void)
    {
        return SomeLibraryFunction( 8, 34.4 );
    }

But of course the problem with this is the lifetimes of the arguments (i.e.
8, 34.4). There's no problem in this specific snippet because they are
intrinsics, but we'd have a problem if they were more complicated,
specifically if they were generated from local variables in 'main':

    int main(int argc, char **argv)
    {
        SomeClass var( argc );

        prvalue x = SomeLibraryFunction( var );

        Func(x);
    }

I think the way to deal with this is for the original template function:

    template<typename T>
    void Func(T &&arg)
    {
        T var( std::forward<T>(arg) );
    }

to be implemented by the compiler as though it were:

    template<typename T>
    void Func( T (*pf)(int,double), int &&arg1, double &&arg2 )
    {
        T var( pf(arg1, arg2) );
    }

and to do away with the 'prvalue' keyword altogether so that 'main' would
then simply become:

    int main(int argc, char **argv)
    {
        SomeClass var( argc );

        Func( SomeLibraryFunction(var) );
    }

So then all you have to do is upgrade your compiler and hit "Rebuild" on
code written 5 years ago, and the compiler gets rid of redundant copy/move
operations, instead allowing a function to take a PRvalue as an argument.
This would also allow us in some instances to use classes that are both
uncopyable and unmoveable (such as std::lock_guard).

Received on 2025-10-20 07:41:34