c++ - GCC 忽略重写成员函数上的 nodiscard 属性是否正确?

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

由于 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 中的一种错误(不太可能,因为编译器资源管理器中的每个可用版本,从 8.1 到 11.1,都会产生相同的结果),还是我做错了什么?

最佳答案

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

  • virtual方法
  • 间接寻址。在您的情况下,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]] 的属性, 这适用于所有编译器。

    关于c++ - GCC 忽略重写成员函数上的 nodiscard 属性是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67858389/

    相关文章:

    c++ - Windows C++下链接库中的静态初始化

    C 相互引用静态初始值设定项

    python - 从类属性组合函数

    c# - 如何使用 C# 从标签 xml 中提取属性?

    c++ - 在模板类中重载加法运算符

    c++ - 恢复 "Source Files"和 "Header Files"文件夹

    c++ - sleep 功能无法解决

    c - GCC:使用 -Wcast-qual 将 const 指针转换为数组 typedef 的 const 指针会抛出警告

    c++ - 构造函数和析构函数对 vTable 的 undefined reference

    python - 在 Python 中循环遍历 Protocol Buffers 属性