4

Due to this question and the answers, it's not 100% clear whether attributes are inherited or not, but probably they're not since it's not stated in the standard. That's why if we have only the declaration marked as nodiscard in the base class, and compile using Clang, we only get a warning if we access the object using a "base" pointer.

The problem with the following code is that it does not warn at all when compiling with GCC (versions 8.1 through 11.1). Having nodiscard only in the Child1, in both classes, or only in Base, calling through a Base pointer or a Child1 pointer, all these do not help.

#include <memory>

class Base {
public:
    [[nodiscard]] 
    virtual int getIdentifier() const = 0;
};

class Child1 : public Base {
public:
    [[nodiscard]]
    int getIdentifier() const override {
        return 1;
    }
};

int main()
{
    std::unique_ptr<const Child1> p1 { new Child1 };
    p1->getIdentifier();

    std::unique_ptr<const Base> p2 { new Child1 };
    p2->getIdentifier();
}

Is this a sort of a bug in GCC (not likely since every single version available in Compiler Explorer, from 8.1 to 11.1, produce the same result), or am I doing something wrong?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Tortellini Teusday
  • 1,335
  • 1
  • 12
  • 21

1 Answers1

4

For me it seems a bug, because it works on Clang. But this bug needs 2 conditions to trigger:

  1. virtual method
  2. Indirect addressing. In your case, unique_ptr does it. If you get a simple instance and call function directly, you will see warning.

But if you need a workaround, you can use another attribute. Here is a small sample:

struct A{
    [[gnu::warn_unused_result]]
    virtual int foo() {
        return 1;
    }
};

int main(){
    A a;
    a.foo();
}

This attribute works for both GCC and Clang.

Another suggestion: You can use attribute like [[nodiscard, gnu::warn_unused_result]], This will works for all compilers.

Afshin
  • 8,839
  • 1
  • 18
  • 53
  • 2
    You were faster with your answer, so I'll just add a comment :-) This looks like a [known bug in gcc](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97712). – andreee Jun 06 '21 at 11:28