Attribute [[nodiscard]]

Memory leaks

Functions that allocate resources that have to be released by another function call should be marked with [[nodiscard]]. A typical example would be a function to allocate memory, such as malloc() or the member function allocate() of allocators.

Unexpected or non-intuitive behavior

A good example of a function changing its behavior non-intuitively when not using the return value is std::async() (introduced with C++11). std::async() starts a functionality asynchronously in the background and returns a handle that can be used to wait for the end of the started functionality (and get access to any return value or exception). However, when the return value is not used the call becomes a synchronous call because the destructor of the unused return value is called immediately waiting for the end of the started functionality. Therefore, not using the return value silently contradicts the whole purpose of calling std::async(). Compilers can warn about this when std::async() is marked with [[nodiscard]].

Unnecessary overhead

Another example is the member function empty(), which checks whether an object (container/string) has no elements. Programmers pretty often call this function to “empty” the container (remove all elements): cont.empty();.

This incorrect application of empty() can often be detected because it does not use the return value. Therefore, marking the member function accordingly:

class MyContainer {
public:
   [[nodiscard]] bool empty() const noexcept;
};

helps to detect such an logical error. If for whatever reason you do not want to use a return value marked with [[nodiscard]] you can cast the return value to void:

(void)coll.empty(); // disable [[nodiscard]] 
warning

Notes