Search code examples
c++language-lawyerreturn-value-optimization

Why is public destructor necessary for mandatory RVO in C++?


Please consider the simple example as follows, where the function bar returns an object of class A with private destructor, and mandatory return value optimization (RVO) must take place:

class A { ~A() = default; };
A bar() { return {}; }

The code is accepted by Clang, but rejected by GCC with the error:

error: 'constexpr A::~A()' is private within this context
    2 | A bar() { return {}; }
      |                   ^

https://gcc.godbolt.org/z/q6c33absK

Which one of the compilers is right here?


Solution

  • This is CWG 2426. The destructor is potentially invoked within this context, because even after the initialization of the return A object, it's still possible that the function fails to complete successfully: any temporaries created during the return statement, and automatic local variables that are in scope, must be destroyed, and if the destruction throws, then as part of stack unwinding, the A object is destroyed. Compilers should require the destructor to be accessible at this point.

    Note 1: exceptions thrown by the destructors of local variables in the outermost scope of the function can be caught by a function try block.

    Note 2: after the return object is destroyed, the handler is allowed to execute another return statement. There is an example of this in the standard.