3

There exists code that relies on the fact that local automatic function variables are destroyed after the return value has been created, for example:

1) Unmangling the result of std::type_info::name

std::string demangle(const char* name)
{
    int status = -4;
    std::unique_ptr<char, void(*)(void*)> res {
        abi::__cxa_demangle(name, NULL, NULL, &status),
        std::free
    };
    return (status==0) ? res.get() : name;
}

2) Timing of scope-based lock guards and return values

class C {
    mutable std::mutex _lock;
    map<string,string> deep_member;
public:
    auto get_big_lump()
    {
        std::unique_lock<std::mutex> lock(_lock);
        return deep_member;
    }
};

Where does the standard specify this order is guaranteed?

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
Dev Null
  • 4,731
  • 1
  • 30
  • 46

2 Answers2

8

[stmt.return]/3:

The copy-initialization of the result of the call is sequenced before the destruction of temporaries at the end of the full-expression established by the operand of the return statement, which, in turn, is sequenced before the destruction of local variables ([stmt.jump]) of the block enclosing the return statement.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
2

You tagged multiple language revisions. So I'll note that the quote @songyuanyao brings was not always there. It was amended under DR 1885, which details how the return statement was under-specified. Specifically the sequencing related wording was missing in C++14, and that was amended in C++17 under the DR.

Practically, your code is likely correct in C++14 too. Vendors have a high QoI standard.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458