Why is unique_ptr::release not defined with [[nodiscard]]?

Viewed 347

C++17 added [[nodiscard]].

C++20 added the use of [[nodiscard]] on empty methods, e.g. vector::empty() -- maybe, to avoid user confusion with the method clear (i.e. calling empty() accidentally to clear the vector).

Why didn't C++20 use this opportunity to add [[nodiscard]] to unique_ptr::release?


Is there a valid reasonable scenario in which one would call unique_ptr::release without taking the returned value?


In the same manner of avoiding user confusion (if this was the reason for adding [[nodiscard]] to the empty methods) - the name release was always very confusing, sounds like, well... something is going to be released here.

Adding [[nodiscard]] could fix this name issue, in a way.

3 Answers

This is addressed in the paper that added [[nodiscard]] to many of the functions. From P0600R1 this is the remark about adding [[nodiscard]] to unique_ptr::release()

Titus: at Google 3.5% of calls would fail, but analysis showed that it was correct (but weird ownership semantics). See reflector email.

Because you've previously retrieved the pointer value and done stuff with it.

Simple approximation:

unique_ptr<someclass> ptr;
// ...
someclass *s = ptr.get();
if (s->are_we_there_yet()) {
    ptr.release();
    // finish up with s...
    s->close_garage_door();
    delete s;
}
// returns true on success
bool run_a_thing(void (*)(void*), void* context);

struct state {
    // whatever
};

void runner(void* context) {
    std::unique_ptr<state> s(static_cast<state*>(context));
    // do things
}

void run_thing() {
    auto s = std::make_unique<state>(....);
    if (run_a_thing(runner, s.get())) {
        s.release();
    }
}

This is basically the structure of libstdc++'s std::thread. run_a_thing is pthread_create.

Related