T O P

  • By -

-Ros-VR-

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.


Conscious_Yam_4753

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.


ToughReplacement7941

> 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 


Raknarg

why queries should always use querying language, like is_empty()


ToughReplacement7941

There should be a compiler warning if you create a function that returns a Boolean but doesn’t start with the name “is” :)


StackedCrooked

Even worse is confusing std::unique_ptr reset() with release().


DryPerspective8429

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.


Plazmatic

I thought it was changed to "implementors \*may\* put nodiscard wherever they want", or maybe that's in c++26?


jaskij

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.


jonathanhiggs

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


Emergency-Pear-1314

How did I not know about std ignore. This language is such a treasure trove


jonesmz

Wasn't `std::ignore = some_function();` only made into a supported thing during the most recent committee meeting? E.g. C++26.


jonathanhiggs

It was intended for structured decomposition, but afaik this has been possible since it was introduced in 11, definitely possible in 17


jaskij

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.


cpp_learner

Consider filing a bug report at https://gcc.gnu.org/bugzilla/.


n1ghtyunso

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!


no-sig-available

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)


13steinj

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.


cpp_learner

We should urge the implementors to document their nodiscard policy. Libc++ has this at https://libcxx.llvm.org/DesignDocs/NodiscardPolicy.html.


jaskij

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?


STL

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.)


jaskij

Nice! Not that I can use MSVC.


NilacTheGrim

But what if you just wanted to exercise your CPU to keep it in shape?


bert8128

You can cast the result to void: (void)a+b;


susanne-o

or rather ``` std::ignore = a + b; ``` https://en.cppreference.com/w/cpp/utility/tuple/ignore


xorbe

What about `auto _ = a + b;`. I like that std::ignore trick, heh.


NilacTheGrim

`_` .. that always makes me nervous due to identifiers in the global namespace starting with `_` being reserved for the implementation..


HolyGarbage

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.


bert8128

Good point. Does (void)(a+b) do the trick?


HolyGarbage

Yes. But as the OP points out, it makes no difference for `std::chrono::duration`.


bert8128

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.


sebamestre

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


Beetny

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


Sinomsinom

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]]


PunctuationGood

Your example may be a bit too contrived. `-Wall` includes `-Wunusued-value` which would warn in this scenario.


jaskij

It doesn't, that's the thing. Neither on 14.1.1 nor on trunk.


xorbe

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.


fm01

Idk, any static code analysis tool should flag this immediately, so is a compiler warning even necessary?


Firm-Survey-31

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?


PunctuationGood

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?


kojima100

The compiler? Which both gcc and Clang warn on when using -Wunused-value


415_961

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.


jaskij

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.