Search code examples
c++c++17nodiscard

Is it possible to ignore [[nodiscard]] in a special case?


C++17 has a new attribute, [[nodiscard]].

Suppose, that I have a Result struct, which has this attribute:

struct [[nodiscard]] Result {
};

Now, if I call a function which returns Result, I got a warning if I don't check the returned Result:

Result someFunction();

int main() {
    someFunction(); // warning here, as I don't check someFunction's return value
}

This program generates:

warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]

So far, so good. Now suppose, that I have a special function, for which I still want to return Result, but I don't want this warning generated, if the check is omitted:

Result someNonCriticalFunction();

int main() {
    someNonCriticalFunction(); // I don't want to generate a warning here
}

It is because, someNonCriticalFunction() does something non-critical (for example, something like printf - I bet that no-one checks printf's return value all the time); most cases, I don't care if it fails. But I still want it to return Result, as in some rare cases, I do need its Result.

Is it possible to do this somehow?


Possible solutions which I don't like:

  • I would not like calling it as (void)someNonCriticalFunction(), because this function is called a lot of times, it is awkward
  • creating a wrapper around someNonCriticalFunction(), which calls (void)someNonCriticalFunction(): I don't want to have a differently named function just because of this
  • removing [[nodiscard]] from Result, and add it to every function which returns Result

Solution

  • I recommend the option you ruled out:

    "removing [[nodiscard]] from Result, and add it to every function which returns Result."

    But since you don't seem happy with it, here's another solution, using bog-standard inheritance:

    struct [[nodiscard]] Result {
    };
    
    struct DiscardableResult: public Result {
    };
    

    For the functions where you can discard the result, use DiscardableResult as return type:

    Result func1();
    DiscardableResult func2();
    
    func1(); // will warn
    func2(); // will not warn