【问题标题】:Is GCC correct to ignore the nodiscard attribute on overridden member functions?GCC 是否正确忽略了被覆盖的成员函数上的 nodiscard 属性?
【发布时间】:2021-08-23 18:09:52
【问题描述】:

由于this 问题和答案,属性是否被继承并不是 100% 清楚,但可能不是,因为标准中没有说明。这就是为什么如果我们在基类中只有标记为 nodiscard 的声明,并使用 Clang 进行编译,我们只会在使用“基”指针访问对象时收到警告。

以下代码的问题是它在使用 GCC(版本 8.1 到 11.1)编译时根本不会发出警告。 nodiscard 仅在 Child1 中,在两个类中,或仅在 Base 中,通过 Base 指针或 Child1 指针调用,所有这些都无济于事。

#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();
}

这是 GCC 中的一种错误(不太可能,因为 Compiler Explorer 中可用的每个版本,从 8.1 到 11.1,都会产生相同的结果),还是我做错了什么?

【问题讨论】:

  • 对我来说,这似乎是一个 GCC 错误。 Clang 工作正常。

标签: c++ gcc attributes language-lawyer compiler-bug


【解决方案1】:

对我来说这似乎是一个错误,因为它适用于 Clang。但是这个bug需要2个条件才能触发:

  1. virtual方法
  2. 间接寻址。在您的情况下,unique_ptr 可以做到。如果你得到一个简单的实例并直接调用函数,你会看到警告。

但如果您需要解决方法,您可以使用另一个属性。这是一个小样本:

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

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

此属性适用于 GCC 和 Clang。

另一个建议:您可以使用[[nodiscard, gnu::warn_unused_result]] 之类的属性,这适用于所有编译器。

【讨论】:

  • 您的回答更快,所以我将添加评论 :-) 这看起来像 known bug in gcc。
猜你喜欢
  • 2018-11-11
  • 1970-01-01
  • 2012-05-13
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-07
  • 1970-01-01
相关资源
最近更新 更多