c++c++17temporaryxvalueprvalue

The C++17 compiler (gcc or Microsoft Visual C++), does it have an option that prohibit the feature "not produce a temporary"


How can I told to С++17 compiler to create temporary in the following case (i.e. The C++17 compiler must considered copy/move operation, like C++11 and C++14 compilers do)

class A{
    public:
        A(){}
        A(const A&)=delete;
        A(A&&)=delete;
};
A f(){
    return A();
}
int main(){
    auto a=f();
}

Output (c++14 - this is what I want):

gcc -std=c++14 ./a.cpp
./a.cpp: In function ‘A f()’:
./a.cpp:8:11: error: use of deleted function ‘A::A(A&&)’
  return A();
           ^
./a.cpp:5:3: note: declared here
   A(A&&)=delete;
   ^
./a.cpp: In function ‘int main()’:
./a.cpp:11:11: error: use of deleted function ‘A::A(A&&)’
  auto a=f();
           ^
./a.cpp:5:3: note: declared here
   A(A&&)=delete;
   ^

Output (c++17):

gcc -std=c++17 ./a.cpp
./a.out

(successfully run)

My customers have a ton of C++11 code and C++17 compilers: gcc 8.3.0, and Microsoft C++ compilers (from Visual Studio 2017 and 2019). And there are many places that contain the code above. The C++17 compiler, does it have an option that prohibit the feature "not produce a temporary" in such a case ?


Solution

  • You cannot (and should not) deactivate guaranteed elision. However, if you want to prevent it in a specific case, all you need to do is not use a prvalue:

    A f(){
        A a{};
        return a;
    }
    

    That will require that A can be moved, though the move can (and almost certainly will) still be elided.

    One of the main points of guaranteed elision is that you now can return prvalues of an immoveable type. This allows you to do more complex initialization through factory functions. This is not a thing that you should want to prevent globally.