Skip to content

Conversation

@shyouhei
Copy link

@shyouhei shyouhei commented Jul 1, 2019

Hello.

While I agree with the values of [[nodiscard]] attribute in general, applying it to increments rather bothers me than being insightful. For instance I hate being warned by the following reproduction code:

#include "tao/operators.hpp"

class foo : public tao::operators::incrementable<foo> {
  private:
    int i;

  public:
    foo &operator++() noexcept
    {
        i++;
        return *this;
    }
    bool operator!=(const foo &f [[maybe_unused]]) const &noexcept
    {
        return /* fake */ false;
    }
};

int
main()
{
    for (foo i; i != foo(); i++) {
        // ...
    }
}

Above for loop warns like this:

% clang++-8 -std=c++2a tmp.cpp
tmp.cpp:22:30: warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]
    for (foo i; i != foo(); i++) {
                             ^~
1 warning generated.

Can you consider relaxing the restriction?

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 6d7982a on shyouhei:master into 93b7139 on taocpp:master.

@ColinH
Copy link
Member

ColinH commented Jul 1, 2019

With operator++ you have two versions, the pre-increment and the post-increment. (Pre-increment is ++i where you increment the value and then use/return it (the incremented value), post-increment is i++ where you use/return the non-incremented original value and it's incremented "afterwards").

Since the post-increment version is (relatively) more complicated, in terms of both semantics and implementation, it is generally considered good style to prefer the pre-increment version of operator++, and only use post-increment when you really need its "special" semantics.

This explains the reasoning behind the nodiscard for post-increment operator++.

If you always use pre-increment in cases where you don't need post-increment semantics, which in particular includes cases where you don't immediately use the return value of the operator, then it's good for post-increment operator++ to be nodiscard.

It helps you find cases where you can switch to the "simpler" pre-increment.

(Of course pre-increment operator++ should not usually be nodiscard since you'd otherwise lose the possibility of calling operator++ purely for the side-effect, i.e. without using the return value.)

@shyouhei
Copy link
Author

shyouhei commented Jul 1, 2019

Thank you for a quick response. So you think postfix increments should always be used with the return values. That in fact explains the current implementation. While I don't think it's necessary to prefer the "simplicity" of prefix increments, that's ultimately my preference. I understood your intention. Let me close this. Thank you for taking time!

@shyouhei shyouhei closed this Jul 1, 2019
@ColinH
Copy link
Member

ColinH commented Jul 1, 2019

You're welcome! Plus it's a good idea to occasionally revisit previous design decisions and see whether they still hold up...

@d-frey
Copy link
Member

d-frey commented Jul 1, 2019

I wish one could add a reason to nodiscard - and apparently I'm not the only one: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1301r2.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants