C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Stop gap required for NRVO until Anton's paper is assimilated

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Sun, 14 Jul 2024 16:25:14 +0100
Bear with me as a copy-paste from a few posts . . .

Firstly Tiago said:
> You will not be able to write std::factory without adding to the compiler
> something akin to a core addition, and it will not be able to figure out
> when it could nrvo any better than what it does now.

And then Sebastian replied:
> Hasn't Frederik solved it except for constexpr'ness?

And then Tiago came back with:
> No. A class that optionally nrvo will never be a guaranteed nrvo.
> You can’t do it by just writing a function on existing code, you
> need something that doesn’t yet exist to do it."


Tiago is incorrect in thinking that my implementations of 'factory'
and 'after_factory' don't guarantee NRVO. My implementations will work
on _every_ C++ compiler, from Arduino microcontrollers to Visual
Studio, and they will always achieve NRVO. Here's how you would return
a locked mutex by value from a function:

    mutex Func(void)
    {
        return factory<mutex>( [](auto &a){ a.lock(); } );
    }

The only place where my implementation falls short is that it's not constexpr.

I foresee in C++26 that if a compiler vendor has a standard header
file called <factory>, then it could contain my implementation which
contains code as follows:

    using SrcType = Derived<T> (*const)(Setup&&,Params&&...);
    using DstType = T (*const)(Setup&&,Params&&...);
    constexpr auto src = &Derived<T>::template
Maker<Setup&&>::template Make<Params&&...>;
    DstType const dst = bit_cast<DstType>(src);
    return dst( forward<Setup>(setup), forward<Params>(args)... );

The only thing that needs to change is the second-last line. Instead
it will need to be something like:

    DstType const dst = __bit_cast_function_pointer_constexpr(DstType,src);

The compiler magic here will be that
"__bit_cast_function_pointer_constexpr" performs a constexpr bit_cast
from one function pointer type to another. This is no more a language
extension than is the libstdc++ implemention of
"std::has_virtual_destructor". Actually let's look at how
"std::has_virtual_destructor" is implemented:

"std::has_virtual_destructor" cannot be implemented using standard
C++. It needs compiler support (aka "compiler magic"). But here's the
wording copy-pasted directly from the C++23 Standard:

    Template: template<class T> struct has_virtual_destructor;
    Conditions: T has a virtual destructor (11.4.7)
    Pre-conditions: If T is a non-union class type, T shall be a complete type.

The Standard doesn't even mention that this particular function needs
compiler support. The Standard doesn't care that it cannot be
implemented without compiler support. The Standard just dictates,
"This will work the way I say it does". Anyway here's a typical
implementation of it:

    template<typename T>
    struct has_virtual_destructor {
        inline static constexpr bool value = __has_virtual_destructor(T);
    };

The compiler support here is the operator "__has_virtual_destructor".
This is not considered to be a "core language change" because the
"__has_virtual_destructor" operator is not made available to the
programmer to use in their own code.

Similarly, if a compiler vendor implements 'factory' and
'after_factory' to be constexpr, then the vendor can use
"__bit_cast_function_pointer_constexpr" in their own header files
without making it available for use by the everyday programmer in
their own source and header files.

I've decided I'm going to go all the way with this proposal . . . Two
days ago I emailed Nevin the worldwide vice-chair to get a P number,
and so I'll share the P number once I receive it in a day or two.
C++26 shall have 'factory' and 'after_factory'.

By the way I'm open to suggestions to rename the two functions. For
example 'factory' could be called "create_prvalue", and
'after_factory' could be 'modify_prvalue' . . . something along those
lines.

Received on 2024-07-14 15:25:23