nodiscard in C++
Introduced in C++17
1. Introduction
Checkout how the declaration of std::vector<T, Allocator>::empty
changes over different C++ versions. Why is it important and how should we use it?
[[nodiscard]]
is a new attribute introduced in C++17. It can be appended to either a function signiture or type declaration to specify that the return value is important and should not be discarding. The compiler will shows warnings if we ignore the return value.
2. Function
Use nodiscard
as function signiture.
1 |
|
Console message:
1 | <source>: In function 'int main()': |
This is a common misuse of the empty()
method. The purpose might seem to empty the vector’s contents, but the correct method to use is clear()
. In this instance, the [[nodiscard]] attribute warns the compiler that the return value from empty()
should not be ignored, highlighting its importance. From C++20 onwards, it’s possible to include a custom message within the [[nodiscard]] attribute, which can help explicitly point out this kind of issue in the code.
3. Type declaration
1 |
|
Console output:
1 | <source>: In function 'int main()': |
It is important to capture the type of error and execute appropriate actions based on the returned value. Doing so can help avert possible bugs in the code.
4. Constructor
Sometimes, instead of applying [[nodiscard]] to an entire type declaration, as in the case above with an ErrorType that indicates the results of execution, we might prefer to specifically apply [[nodiscard]] to constructors.
1 | std::unique_lock<std::mutex> lock{mu}; |
In this scenario, constructors for both unique_lock
and unique_ptr
are invoked, returning objects that are then used for further operations and resource management. Consider a situation where we create our own class or struct that allocates resources within its constructor. If, in the main function, we call this constructor without assigning the returned object to a variable, the allocated resources would become inaccessible, leading to memory leaks and potential issues with resource management.
Let’s reuse the example from section 1.
1 |
|
Console output:
1 | <source>: In function 'int main()': |
Start using [[nodiscard]]
, you can make your code more robust.
References
nodiscard in C++