I don't know, but nodiscard was added to the standard 6 years after the chrono library was, and the chrono library had already existed for many years before c++11, so maybe just nobody has gotten around to updating it to use it yet.
Very, very few std library functions are nodiscard. Functions that allocate memory are marked nodiscard, since discarding their result is a serious bug, and the empty() method on containers are, because people often mistakenly think that calling them empties the container rather than checking that they are empty.
I guess there is an argument to be made that any function without side effects should be nodiscard, but some might feel that this is an unreasonable burden on standard library implementations, and the C++ rules are largely written by compiler writers.
> empty() method on containers are, because people often mistakenly think that calling them empties the container
Sometimes I wake up In the middle of the night, annoyed about this
If I'm reading the newly-updated cppref [compiler support [page](https://en.cppreference.com/w/cpp/compiler_support) correctly, it seems that [P2422R0](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2422r0.html) got voted in and the standard library will remove its `[[nodiscard]]` annotations entirely in C++26; leaving it at the discretion of library vendors.
In my case, this particular bug could have led to not respecting hardware timing constraints. You could argue that *is* a major issue. But I get your point.
As the other commenter said, the annotation is slated for removal from the standard library anyway.
I mark pretty much all non-void functions as nodiscard for the simple reason it is better to be explicit and use std::ignore when it really isn’t needed than to have something you probably didn’t intend getting missed
Yup. There are rare cases where it's an infallible impure function and the return is a convenience. As an example: CRCs. Adding bytes returns the current value, but there is also a separate getter for it.
I say infallible, because I do embedded and disable exceptions, using `std::expected` instead.
You are allowed to do stupid things, and nothing *too* bad happens, like leaking resources.
And soon this will be purely quality of implementation, so not really a standard defect.
[https://isocpp.org/files/papers/P2422R1.html](https://isocpp.org/files/papers/P2422R1.html)
I disagree with the approach. I can understand that it's QoI and all that, but sometimes the point of something being in the standard and not a recommendation is to twist an implementor's arm and void the (on some platforms) implementor monopoly.
I'm not super familiar with the standard and how it's written. Since it's a quality of implementation thing, will implementations be allowed to add the attribute themselves? Can they do that already?
MSVC warns, because we love `[[nodiscard]]` more than cats love yarn: https://godbolt.org/z/1YPjE73Ye
(Implementations have always been and will always be allowed to add `[[nodiscard]]` to whatever they like, according to their best judgement.)
This is relevant to the post from u/NilacTheGrim. And u/stl says that the MSVC implementation is already nodiscard. So even if you deploy using gcc or clang that’s a good reason to compile on MSVC as well.
I think the comittee recently decided they would not standardize attributes on stdlib functions and leave them to implementers, so its just a quality of implementation issue. Complain with your vendor i guess
See https://www.reddit.com/r/cpp/comments/1cmdlit/tokyo_iso_c_report_ville_wins_sankel_award/ where the standard [[nodiscard]] policy was last discussed
There are currently discussions about removing [[nodiscard]] from the standard entirely and leaving it up to the implementation to mark whatever they feel for as [[nodiscard]]. One of the main reasons I read for this was because discussions of what should and shouldn't be [[nodiscard]] and which pre [[nodiscard]] functions/methods should be made [[nodiscard]] were taking up too much time that could be used for more productive purposes.
So don't get too hung up on what is and isn't marked [[nodiscard]]
I think because `a + b` is a function call, and the compiler can't be 100% sure there are no side effects. So it has to err to the side of not giving a false warning.
Yeah, why having a clock on phones, if people could easily buy a watch for their wrist. 😂
I think you're turning things upside down here. Why force people to employ static analyzers for issues the compiler can easily diagnose right away?
The compiler sees things very differently than our eyes. The + here is the builtin integer addition operator and it can make many assumptions safely. But that's not the case for `std::chrono::operator+` function.
My actual project is on slightly older GCC 13.2, with `-Wall -Werror -fanalyzer`. Still didn't warn.
I could set up something better, but there would be a lot of false positives in external libraries I'm building from sources, so... Yeah.
I don't know, but nodiscard was added to the standard 6 years after the chrono library was, and the chrono library had already existed for many years before c++11, so maybe just nobody has gotten around to updating it to use it yet.
Very, very few std library functions are nodiscard. Functions that allocate memory are marked nodiscard, since discarding their result is a serious bug, and the empty() method on containers are, because people often mistakenly think that calling them empties the container rather than checking that they are empty. I guess there is an argument to be made that any function without side effects should be nodiscard, but some might feel that this is an unreasonable burden on standard library implementations, and the C++ rules are largely written by compiler writers.
> empty() method on containers are, because people often mistakenly think that calling them empties the container Sometimes I wake up In the middle of the night, annoyed about this
why queries should always use querying language, like is_empty()
There should be a compiler warning if you create a function that returns a Boolean but doesn’t start with the name “is” :)
Even worse is confusing std::unique_ptr reset() with release().
If I'm reading the newly-updated cppref [compiler support [page](https://en.cppreference.com/w/cpp/compiler_support) correctly, it seems that [P2422R0](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2422r0.html) got voted in and the standard library will remove its `[[nodiscard]]` annotations entirely in C++26; leaving it at the discretion of library vendors.
I thought it was changed to "implementors \*may\* put nodiscard wherever they want", or maybe that's in c++26?
In my case, this particular bug could have led to not respecting hardware timing constraints. You could argue that *is* a major issue. But I get your point. As the other commenter said, the annotation is slated for removal from the standard library anyway.
I mark pretty much all non-void functions as nodiscard for the simple reason it is better to be explicit and use std::ignore when it really isn’t needed than to have something you probably didn’t intend getting missed
How did I not know about std ignore. This language is such a treasure trove
Wasn't `std::ignore = some_function();` only made into a supported thing during the most recent committee meeting? E.g. C++26.
It was intended for structured decomposition, but afaik this has been possible since it was introduced in 11, definitely possible in 17
Yup. There are rare cases where it's an infallible impure function and the return is a convenience. As an example: CRCs. Adding bytes returns the current value, but there is also a separate getter for it. I say infallible, because I do embedded and disable exceptions, using `std::expected` instead.
Consider filing a bug report at https://gcc.gnu.org/bugzilla/.
this is the correct approach, especially for the future where nodiscard is pure QoI. If their QoI is lacking, it IS a bug and must be reported!
You are allowed to do stupid things, and nothing *too* bad happens, like leaking resources. And soon this will be purely quality of implementation, so not really a standard defect. [https://isocpp.org/files/papers/P2422R1.html](https://isocpp.org/files/papers/P2422R1.html)
I disagree with the approach. I can understand that it's QoI and all that, but sometimes the point of something being in the standard and not a recommendation is to twist an implementor's arm and void the (on some platforms) implementor monopoly.
We should urge the implementors to document their nodiscard policy. Libc++ has this at https://libcxx.llvm.org/DesignDocs/NodiscardPolicy.html.
I'm not super familiar with the standard and how it's written. Since it's a quality of implementation thing, will implementations be allowed to add the attribute themselves? Can they do that already?
MSVC warns, because we love `[[nodiscard]]` more than cats love yarn: https://godbolt.org/z/1YPjE73Ye (Implementations have always been and will always be allowed to add `[[nodiscard]]` to whatever they like, according to their best judgement.)
Nice! Not that I can use MSVC.
But what if you just wanted to exercise your CPU to keep it in shape?
You can cast the result to void: (void)a+b;
or rather ``` std::ignore = a + b; ``` https://en.cppreference.com/w/cpp/utility/tuple/ignore
What about `auto _ = a + b;`. I like that std::ignore trick, heh.
`_` .. that always makes me nervous due to identifiers in the global namespace starting with `_` being reserved for the implementation..
That will not do what you want it to. C-style casts has a higher precedence than arithmetic operators. Luckily in this case it won't compile.
Good point. Does (void)(a+b) do the trick?
Yes. But as the OP points out, it makes no difference for `std::chrono::duration`.
This is relevant to the post from u/NilacTheGrim. And u/stl says that the MSVC implementation is already nodiscard. So even if you deploy using gcc or clang that’s a good reason to compile on MSVC as well.
I think the comittee recently decided they would not standardize attributes on stdlib functions and leave them to implementers, so its just a quality of implementation issue. Complain with your vendor i guess
See https://www.reddit.com/r/cpp/comments/1cmdlit/tokyo_iso_c_report_ville_wins_sankel_award/ where the standard [[nodiscard]] policy was last discussed
There are currently discussions about removing [[nodiscard]] from the standard entirely and leaving it up to the implementation to mark whatever they feel for as [[nodiscard]]. One of the main reasons I read for this was because discussions of what should and shouldn't be [[nodiscard]] and which pre [[nodiscard]] functions/methods should be made [[nodiscard]] were taking up too much time that could be used for more productive purposes. So don't get too hung up on what is and isn't marked [[nodiscard]]
Your example may be a bit too contrived. `-Wall` includes `-Wunusued-value` which would warn in this scenario.
It doesn't, that's the thing. Neither on 14.1.1 nor on trunk.
I think because `a + b` is a function call, and the compiler can't be 100% sure there are no side effects. So it has to err to the side of not giving a false warning.
Idk, any static code analysis tool should flag this immediately, so is a compiler warning even necessary?
Yeah, why having a clock on phones, if people could easily buy a watch for their wrist. 😂 I think you're turning things upside down here. Why force people to employ static analyzers for issues the compiler can easily diagnose right away?
OP's example is, in my eyes, really no different than: int a = 10; int b = 20; a + b; What tool should warn us in such a case?
The compiler? Which both gcc and Clang warn on when using -Wunused-value
The compiler sees things very differently than our eyes. The + here is the builtin integer addition operator and it can make many assumptions safely. But that's not the case for `std::chrono::operator+` function.
My actual project is on slightly older GCC 13.2, with `-Wall -Werror -fanalyzer`. Still didn't warn. I could set up something better, but there would be a lot of false positives in external libraries I'm building from sources, so... Yeah.