【问题标题】:gnu::warn_unused_result attribute ignored if return class has destructor如果返回类具有析构函数,则忽略 gnu::warn_unused_result 属性
【发布时间】:2016-11-11 15:38:51
【问题描述】:

如果他/她不保存某个函数的返回值,我想警告用户,但如果该函数返回一个具有非默认析构函数的类,则它不起作用。

假设以下代码:

struct A {};
struct B { ~B() {} };

[[ gnu::warn_unused_result ]]
A foo() { return A{}; }

[[ gnu::warn_unused_result ]]
B bar() { return B{}; }

int main()
{
    foo(); // warning
    bar(); // no warning
    return 0;
}

使用 g++ 6.2.1 编译时,只有foo() 会产生警告:

$ g++ -Wall -Wextra ./test.cpp 
./test.cpp: In function ‘int main()’:
./test.cpp:13:9: warning: ignoring return value of ‘A foo()’, declared with attribute warn_unused_result [-Wunused-result]
     foo();
         ^

我了解调用 B 的析构函数可能被视为“使用结果”,但问题是:

  • 这是预期行为还是 g++ 中的错误/功能?
  • 在这种情况下,有没有办法强制编译器发出警告?
  • C++17 的[[ nodiscard ]] 的行为是否相同?

【问题讨论】:

  • 我认为这是一个错误。但我不知道GCC 作者的意图。这样做的问题是,如果稍微修改返回对象的类,行为可能会从一个构建更改为下一个构建。我看不出有人会觉得那是可取的。你的项目无法控制的库对象呢?

标签: c++ g++ language-lawyer


【解决方案1】:

这是预期行为还是 g++ 中的错误/功能?

这是一个 QoI 问题,所有类似的警告也是如此。 gcc 7 确实bar() 发出警告,因此虽然不发出警告不是错误,但它更像是 gcc 6.2 中缺少的功能。

C++17 的 [[ nodiscard ]] 的行为是否相同?

这也是实现定义的。 [dcl.attr.nodiscard]中的标准中有一个非规范性注释:

外观 除非明确说明,否则不鼓励将 nodiscard 调用作为潜在评估的丢弃值表达式(第 5 条) 投到无效。 鼓励实现在这种情况下发出警告。这通常是因为 丢弃 nodiscard 调用的返回值会产生令人惊讶的后果。

在这种情况下,实现不需要发出警告。但他们可能会尝试这样做。

【讨论】:

  • QoI 代表什么?实施质量(猜测)?
  • @Kane 是的。猜对了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
  • 2016-05-25
相关资源
最近更新 更多